Как передать переменные команде awk с условиями?

У меня есть цикл while, который считывает данные из файла с названиями городов:

название города:

COIMBATORE MADURAI PONDICHERRY SALEM TRIPUR TIRUCHI TIRUNELVELI TUTUCORIN VELLORE 

и используя команду awk в цикле while и пытаясь прочитать переменную, определенную во время цикла, снова в выражении awk , это не работает и дает мне ошибки. Я понимаю, что awk требует, чтобы переменные были определены для своего тела отдельно, чтобы awk мог понять использование переменной и мог прочитать ее значение.

Мой цикл while выглядит следующим образом:

 while read city do awk -F, '{ if ( $1 == "ACTIVE" ) && ( $2 == "$city" ) print $1 }' siteDBName >> count SUM=`awk '{ sum += $1 } END { print sum }' count` done < city_name 

где файл siteDBName содержит несколько столбцов с данными, подобными следующим:

siteDBName:

 ACTIVE,COIMBATORE,MGT500,1,5,7.... INACTIVE,MADURAI,GT500,5,6,7... ACTIVE,SALEM,TR600,6,4,6... ACTIVE,COIMBATORE,GT500,4,5,6... .. .. 

Здесь я попытался использовать awk -vc=$city вместе с остальными утверждениями, но это тоже дало мне ошибки.

Как я могу использовать переменную, используемую и инициализированную в цикле while внутри оператора awk внутри этого цикла while?

3 Solutions collect form web for “Как передать переменные команде awk с условиями?”

У вас есть два основных варианта: i) использовать -v для передачи переменной awk или ii) закрыть ' вокруг скрипта awk , использовать переменную оболочки и продолжить ' .

  1. Использовать -v

     while read city do awk -vcity="$city" -F, '{ if ( $1 == "ACTIVE" && $2 == city ){print $1} }' siteDBName >> count done < city_name 
  2. Закрыть цитату

     while read city do awk -F, '{ if ( $1 == "ACTIVE" && $2 == "'$city'" ){print $1} }' siteDBName >> count done < city_name 

Я удалил строку SUM= так как это было i) неправильно, $1 ACTIVE поэтому добавление не имеет смысла и ii) результат SUM недоступен вне цикла while. См. Мой альтернативный подход ниже, чтобы сделать это правильно.

Также обратите внимание, что при таком подходе вам нужно несколько раз прочитать файл siteDBName . Более эффективная версия:

 $ awk -F, '{ if(NR==FNR){cities[$1]++;} else if($1=="ACTIVE" && $2 in cities ){sum++} } END{print sum,"active cities"}' city_name siteDBName 3 active cities 

Так же, как @cuonglm и @YoMismo заявили, что вы используете неправильную переменную и неправильный способ ее ссылки. Это должно быть что-то вроде:

 while read city do awk -vc="$city" -F, '{ if ( $1 == "ACTIVE" && $2 == c ) print $1 }' siteDBName >> count SUM=`awk '{ sum += $1 } END { print sum }' count` done < city_name 

Если вы заинтересованы только в SUM

 grep -cf <(sed s/^/\^ACTIVE,/ city_name) siteDBName 

или для больших файлов

 grep -f city_name siteDBName | grep -c ^ACTIVE 
  • exec перенаправляет в bash
  • Вставьте новую строку после разбитой последовательности чисел awk / unix / shell scripting
  • Извлечь zip-файлы в каталог на основе шаблона zip-имени
  • SSH дважды и запустить команду, экранируя символ?
  • Что делает «sudo chown -R hadoop: hadoop hadoop»?
  • Point и нажмите Ubuntu 16.04 bash-скрипт случайным образом изменяет поведение вывода
  • Как правильно собрать массив строк в zsh
  • Использование nohup в /etc/init.d/service
  • Синтаксис оболочки: как правильно использовать \ для разрыва строк?
  • Использование find в unix для странных имен файлов / каталогов
  • Git Bash для Ubuntu / Linux и Windows требует перезагрузки ssh-agent
  • как мы можем использовать несколько переменных в одиночном для цикла в сценарии оболочки?
  • Linux и Unix - лучшая ОС в мире.