Как мне условно изменить поле csv в определенных строках в зависимости от того, что находится в другом поле?

#csv #awk #sed #element

#csv #awk #sed #элемент

Вопрос:

У меня есть имя файла csv data.csv, как показано ниже

 "check","small and big","address","plot 25,bangalore","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","jggjgg","show"
  

Теперь я хочу sed awk , чтобы команда or заменила поле рядом с адресом в 1-й строке на *** и поле 3-й строки рядом с именем на *** и сохранила его в том же файле csv.

Пример вывода должен быть

 "check","small and big","address","****","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","****","show"
  

Комментарии:

1. awk не будет тривиально обрабатывать сложный CSV-файл RFC4180 с запятыми и / или кавычками в полях. Вам нужно использовать язык, на котором кто-то написал библиотеку CSV, совместимую с RFC4180, например Python, Perl или NodeJS.

2. Можете ли вы попытаться немного прояснить, что вы хотите?

3. @user3755420, дайте мне образец вывода, который вам нужен?

4. Привет, input.csv показан ниже «проверить», «маленький и большой», «адрес», «участок 25, Бангалор», «скрыть» «проверить», «большой и маленький», «номер ph», «7979797», «скрыть» «проверить», «маленькийдля больших «,»name»,»jggjgg»,»show» я хочу, чтобы ouput.csv был «проверкой», «маленьким и большим», «адресом»,»****»,» скрыть», «проверить», «большой и маленький», «номер ph»,»7979797″, «скрыть», «проверить», «от маленького до большого», «имя»,»****»,» показать»

5. в этом файле csv всего три строки? Вы хотели пустую строку между строками?

Ответ №1:

Вы можете попробовать следующую команду awk,

 $ awk -v FS='",' 'NR==1 {gsub (/.*/,""****",$4);} NR==3 {gsub (/.*/,""****",$4);}1' OFS='",' file
"check","small and big","address","****","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","****","show"
  

Форма сортировки, предложенная Томом Фенеком,

 $ awk -v FS='",' 'NR==1||NR==3 {gsub (/.*/,""****",$4);}1' OFS='",' file
"check","small and big","address","****","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","****","show"
  

И через GNU sed,

 $ sed -r '1s/^(.*,")([^"]*)(",.*)$/1****3/g;3s/^(.*,")([^"]*)(",.*)$/1****3/g' file
"check","small and big","address","****","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","****","show"
  

Комментарии:

1. Вместо двух одинаковых блоков вы могли бы просто сделать NR==1||NR==3

2. Спасибо за его работу. Можно ли то же самое подумать, используя sed??

Ответ №2:

Поскольку CSV может быть на удивление сложным для анализа, я предпочитаю использовать правильный анализатор CSV:

 $ cat data.csv
"check","small and big","address","plot 25,bangalore","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","jggjgg","show"
$ ruby -rcsv -i -ne '
  row = $_.parse_csv
  row[3] = "***" if ["address","name"].include? row[2]
  puts row.to_csv(:force_quotes => true)
' data.csv
$ cat data.csv
"check","small and big","address","***","hide"
"check","big and small","ph number","7979797","hide"
"check","small to big","name","***","show"