#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, Отлично работает !! Большое спасибо.