2015-09-04 3 views
6

У меня есть файл сказать a.txt и ниже содержание него:Распечатайте список полей, передаваемых в качестве переменной

bob 1 100    
lincoln 2 200 
chris 3 300   

Содержимое файла, разделенных пробелами.

Используя awk, я мог бы получить доступ к каждому столбцу. Использование ниже команд для печати 1-й и 3-я столбцов, разделенных запятой:

cat a.txt | awk ' { print $1","$3} ' 

и я был успешным.

Теперь я хочу динамически передать критерии из другого сценария оболочки. Говоря критерии, я имею в виду - $1","$3.

Я попробовал команду ниже, но это не сработало.

myvar="$1" 
awk -v a="$myvar" ' { print a } ' a.txt 

но это печатает $1 3 раза есть три строки в a.txt.

Как передать список полей awk таким образом?

+0

'«$ 1»' означает первый аргумент вашего скрипта. как вы назвали свой сценарий? 'script '1" '? Если 'a'' '' '' '' ', вы должны напечатать' $ a' – Kent

+0

«$ 1», «$ 3» - эту часть нужно передавать динамически - вместе с разделителями. скажем, если у меня есть 5 столбцов, я могу отправить что-то вроде $ 1 ", $ 2" - ", $ 3" ​​- "$ 4", "$ 5, т.е. 1 и 2, 4 и 5, разделенные запятыми и остальное -. передайте шаблон из другого файла в качестве аргумента, а команда awk будет в другом файле –

ответ

6

Проблема здесь в том, что в переменной $ вы перешли к AWK интерпретируется буквально - это не может быть используется для обозначения конкретного поля.

Для одного поля, вы могли бы использовать что-то вроде этого:

awk -v field=1 '{ print $field }' file 
bob 
lincoln 
chris 

Для нескольких полей, это немного сложнее:

awk -v fields="1 3" 'BEGIN{ n = split(fields,f) } 
    { for (i=1; i<=n; ++i) printf "%s%s", $f[i], (i<n?OFS:ORS) }' file 
bob 100 
lincoln 200 
chris 300 

Список полей передается в виде строки , который разбивается на массив. Затем массив циклически проходит через printf для вывода каждого поля, за которым следует либо выходной разделитель полей OFS, либо выходной разделитель записи ORS, в зависимости от того, является ли это последним полем или нет. Чтобы разделить поля запятой, вы можете пройти -v OFS=, в качестве опции.

+0

Я рад, что нашел ответ на свой вопрос. Есть ли способ добавить разделители на вывод в случае нескольких файлов. –

+0

Да, вы можете установить' OFS' на что-то другое чем пространство по умолчанию, использующее 'awk -v OFS = 'все, что вам нужно здесь'. –

+0

« $ 1 »,« $ 3 »- эта часть фактического вопроса должна быть передана динамически - вместе с разделителями. Например, если у меня есть 5 столбцов, я должен был бы отправить что-то вроде $ 1 ", $ 2" - ", $ 3" ​​- "$ 4", "$ 5, т.е. 1 & 2, 4 и 5, разделенные запятыми и отдыхая" ". Я буду передавать шаблон из другого файла в качестве аргумента. и команда awk будет в другом файле. Я не могу этого добиться. –

3

Вам нужно будет передать строку с разделителем на awk и внутри awk использовать split, чтобы разделить на этом разделителе.

Что-то, как это должно работать:

awk -v search='1,3' 'BEGIN{split(search, a, ",")} 
       {f=""; for (i=1;i in a;i++) {printf "%s%s", f, $a[i]; f=OFS} print ""}' file 

Выход:

bob 100 
lincoln 200 
chris 300 
+0

Спасибо @TomFenech, я его отредактировал. Как-то 'lenght' работает на BSD (osx) awk. – anubhava

+1

или фиксирует длину при расщеплении' len = split (...) ' – karakfa

2

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

cols="1,3"; cut -d" " -f"$cols" a.txt 

для разделенных запятой выходной трубы к tr ' ' ',' или использовать --output-delimiter="," вариант разреза.

Обратите внимание, что это даст вам возможность определить, вход в закрытом или открытом диапазоне, такие как 1-3 или 2-

Смежные вопросы