Заставьте переменные показать столбец с awk

У меня есть эта переменная:

collumn=2

Я хочу заставить его измениться с 2 столбцами строки, которая запускается с john из файла, с awk.

Например, в этом файле sample.txt:

bill|copper|real|bruce
john|gold|fake|jhin
johny|silver|geniue|madrit

Это не работает:

collumn=2
awk -F '|' /^jonh/ -v collumn="$2" sample.txt
echo "$collumn"

Я хочу, чтобы это распечатало gold.

В основном я хочу изменить значение переменной с awk.

3
задан 14 October 2017 в 07:58

1 ответ

Вы используете два языка: Bash и AWK.

Bash (который является Вашей оболочкой) и AWK является оба языками программирования, и они оба позволяют Вам хранить данные в переменных. Но переменные в Вашей оболочке и переменные в AWK являются абсолютно отдельными. Кроме того, переменные в AWK больше не существуют после того, как Ваш сценарий AWK заканчивается. Таким образом, однажды Ваш awk команда сделана, работая, Ваших переменных AWK не стало.

Можно передать текст формы var=val как параметр командной строки к awk команда. Это присваивает переменную в AWK. Это не влияет на переменные оболочки всегда. Когда Вы используете -v опция (например, -v var=val), это говорит awk команда для присвоения переменной, прежде чем это запустит скрипт AWK, но это - все еще переменная AWK, не переменная оболочки.

Ваша цель состоит в том, чтобы присвоить текст из определенного столбца подобранной строки к переменной оболочки. Можно сделать это. Но сначала, давайте решим более простую проблему. Эта команда находит строки, которые запускаются с john и отображает содержание второго столбца каждой такой строки. Если у Вас есть всего одна строка, которая запускает тот путь, она отображает один объект. Если у Вас нет таких строк, это ничего не отображает, и если у Вас есть несколько строк, которые запускаются с john, затем это отобразит несколько объектов на отдельных строках:

awk -F '|' '/^john/ { print $2 }' sample.txt

Сценарий AWK в той команде /^john/ {print $2}. Я включил его в одинарные кавычки (' ') так, чтобы это рассматривала как единственную строку и не изменила оболочка, прежде чем быть переданным awk команда. Иначе оболочка интерпретировала бы сценарий AWK как пять отдельных слов и операторы для самой оболочки (не AWK), который приведет к нему берущий просто /^john/ как сценарий AWK. Все после того, как это рассматривали бы как имена файлов для передачи awk, который не работал бы. Оболочка также расширилась бы $2, и выполнил бы разделение слова и расширение имени файла (globbing) на результате (хотя включая $2 в двойных кавычках как в Вашем вопросе предотвратил бы разделение и globbing). Вы не хотите ни одной из тех вещей произойти. В целом это - хорошая идея включить Ваши сценарии AWK в одинарные кавычки, таким образом, они передаются искренне awk команда.

С sample.txt файл, показанный в Вашем вопросе, та команда производит этот вывод:

gold
silver

Это печатает текст от двух согласующих отрезков длинной линии, а не всего один. Так как Вы хотите просто gold, Вы, вероятно, действительно не хотите соответствовать всем строкам, которые запускаются с john. Вместо этого Вы, вероятно, хотите соответствовать только строкам, где запись в первом столбце john точно. (Одно из преимуществ решения более простой версии проблемы сначала - то, что оно может помочь Вам совершенствовать свое знание точно, какую проблему Вы хотите решить.) Можно выбрать только строки, первая запись столбца которых точно john как это:

awk -F '|' '$1 == "john" { print $2 }' sample.txt

Это отображается:

gold

Теперь давайте решим полную проблему. Присвоение для окружения переменных не является чем-то, что можно сделать в сценарии AWK. Не только это не часть языка AWK, но awk команда должна была бы быть реализована как часть Вашей оболочки для него, чтобы быть возможной. Это не означает, что Вы не можете сделать то, что Вы хотите сделать - Вы абсолютно можете. Это просто означает, что, вместо того, чтобы пытаться написать код AWK для присвоения переменной оболочки необходимо использовать саму оболочку, чтобы сделать это.

Вы имеете awk управляйте, чтобы отобразил значение, которое Вы хотите присвоенный переменной. Таким образом, можно использовать замену команды в оболочке, чтобы помочь Вам выполнить присвоение. Эта команда присваивает его названной переменной оболочки entry (но можно использовать любое имя, которое Вы любите вместо entry, такой как column):

entry="$(awk -F '|' '$1 == "john" { print $2 }' sample.txt)"

Это работает, потому что оболочка заменяет $( ) и все в нем с выводом, произведенным путем выполнения команды в нем. Это - замена команды. Обратите внимание, что при присвоении переменной оболочки как это у Вас не должно быть пробелов вокруг = знак.

(Между прочим, можно заметить что текст john является цветным выше, как будто это не было эффективно заключено в кавычки. Это - на самом деле ошибка в программном обеспечении, которое обеспечивает подсветку синтаксиса на этом веб-сайте, который происходит, потому что это не полностью анализирует содержание внешнего " ", таким образом, это не знает что внутреннее " " внутри $( ). Это не проблема при фактическом выполнении команды, как бы то ни было.)

Можно проверить это gold был присвоен entry переменная оболочки путем выполнения:

echo "$entry"

Это отобразится:

gold

Для получения дополнительной информации о переменных на языке AWK посмотрите этот раздел 6.1.3 Переменные в Простофиле: Эффективное Программирование AWK, которое является официальной документацией для GNU awk (gawk). Хотя это документирует GNU awk, это объясняет, что характерно для GNU awk и что может также использоваться в других реализациях языка AWK. awk команда в Вашей системе Ubuntu быть также mawk или gawk, В зависимости от того, какое программное обеспечение Вы установили и как Вы настроили его. Один способ видеть, который должен работать awk -W version.

2
ответ дан 1 December 2019 в 16:54

Другие вопросы по тегам:

Похожие вопросы: