Как прочитать содержимое CSV-файла и узнать между на основе строкового значения в скрипте оболочки

#bash #shell #awk

Вопрос:

У меня есть 1 файл данных «file1.csv» с данными в двух столбцах, и мне нужно прочитать содержимое файла и определить промежутки между строками на основе значений строки первого столбца «финансы и итого» и аналогично «маркетинг и итого». Сценарий должен найти «финансы» и «общий объем финансирования», затем получить записи между (A,B,D,H), А сценарий должен найти «маркетинг» и «общий объем маркетинга», затем получить записи между (C, E, G). Я не хочу получать записи до строки «Финансы» и после строки «Общий объем маркетинга».

Также необходимо пропустить строки, в которых 2-е или 3-е поля содержат строку nan.

Я попытался использовать приведенный ниже код, но не получил ожидаемого результата.

 while read line do  if [[ $line == "finance" ]]; then  echo $line >> output.csv  else  echo ""  fi done < file1.csv  file1.csv: Departments Accounts ##Header Monthwise data ##Sub Header IT,Amount P,20 q,30 IT Total,50 Finance,Amount A,20 B,30 D,60 H,50 Finance Total,160 <Empty space> Marketing,Amount C,40 E,10 G,60 Marketing Total,110 HR,amount X,20 Y,50 Z,10  

Ожидаемый Результат:

 department,name,amount Finance,A,20 Finance,B,30 Finance,D,60 Finance,H,50 Marketing,C,40 Marketing,E,10 Marketing,G,60   

Ожидаемый результат должен быть сохранен в выходном файле.

Ответ №1:

С показанными вами образцами, пожалуйста, попробуйте следующую awk программу. Простым объяснением было бы установить запятую как FS, OFS для всех строк и напечатать заголовок в самом разделе «НАЧАЛО». Затем в основной программе проверьте различные условия и распечатайте значения соответственно. ПРИМЕЧАНИЕ. Эта программа завершит работу, как только найдет Marketing Total в соответствии с упоминанием ОП.

 awk ' BEGIN{  FS=OFS=","  print "department,name,amount" } /Marketing Total/ { exit } /Finance Total/ || ($2=="nan" || $3=="nan"){ next } /Finance,Amount/ || /Marketing,Amount/ { found=1;first=$1;next } found { print first,$0 } ' Input_file  

ИЛИ в случае, если значение nan необходимо сравнить с учетом регистра, попробуйте выполнить следующий код.

 awk ' BEGIN{  FS=OFS=","  print "department,name,amount" } /Marketing Total/ { exit } /Finance Total/ || (tolower($2)=="nan" || tolower($3)=="nan"){ next } /Finance,Amount/ || /Marketing,Amount/ { found=1;first=$1;next } found { print first,$0 } ' Input_file  

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

1. Поскольку OP немного изменил ввод, теперь отредактированный код.

2. @ RavinderSingh13, я отредактировал данные своего входного файла. Не могли бы вы, пожалуйста, взглянуть и сделать все необходимое. Я попробовал вашу программу, но я получаю столбец заголовка «финансы и сумма» также в OP. Пожалуйста, обратите внимание, что моя операция должна быть записана в выходной файл.

3. @Рамми, конечно, я уже изменил код, пожалуйста, проверьте один раз и дайте мне знать, как это происходит?

4. @ RavinderSingh13, Отлично, и большое спасибо. Отлично работает. Мне нужно еще одно , как справиться,если мы получим значения » nan «(иногда мы получим входной файл, в котором будет пробел между «Общий объем финансирования» и «Маркетинг, сумма») . приложил скриншот.

5. @ RavinderSingh13, Отлично работает !! Большое спасибо.