У меня есть эта переменная:
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.
Вы используете два языка: 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
.