Значения, разделенные табуляцией в awk

92

Как выбрать первый столбец из строки, разделенной табуляцией?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Приведенное выше вернет всю строку, а не только "LOAD_SETTLED", как ожидалось.

Обновить:

Мне нужно изменить третий столбец в значениях, разделенных вкладкой. Следующее не работает.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Однако это работает должным образом, если разделителем является запятая вместо табуляции.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt
Shantanuo
источник
4
awk 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# это то, что я искал. Мой поиск в Google правильный? :)
shantanuo
3
Благодаря этому комментарию я обнаружил: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtпечатать значения, разделенные табуляцией, первых трех столбцов.
Wok
7
Или, может быть, простоawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Джозайя Йодер
3
Как GNU, так и BSD awk поддерживают -vустановку переменных. Некрасиво использовать BEGIN {FS="\t"}внутри встроенной программы , и против любого вклада с открытым исходным кодом, который вы пытаетесь сделать так, скорее всего, будут возражать. Делайте это только в том случае, если вы пишете программный файл . Кроме того, не рекомендуется использовать -Fвместо, -v FS=потому что последнее дает понять, что только FSустанавливается, а не нет OFS. Путаница по поводу последнего пункта - вот что в первую очередь вызвало этот пост. Вот почему так важен «хороший стиль».
Бруно Броноски
1
Пожалуйста, никто и никогда не должен делать то, что продемонстрировал @Wok. Вы не перечисляете разделители полей [Input] в своем выводе. Вы указываете разделитель выходного поля через OFSпеременную.
Бруно Броноски

Ответы:

143

Вам нужно установить OFSпеременную (разделитель полей вывода) как вкладку:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(убедитесь, что вы указали $lineпеременную в операторе echo)

Гленн Джекман
источник
6
Какова цель символа $ в $ '\ t'?
Амр Мостафа
10
Отвечая на свой вопрос из Advanced Bash Scripting Guide : Конструкция расширения строки в кавычках $ '...' - это механизм, который использует экранированные восьмеричные или шестнадцатеричные значения ..., например, quote = $ '\ 042'.
Амр Мостафа
5
@AmrMostafa, очень плохо , что руководство имеет заблуждение объяснения ведущего к мысли , что вы не $в $'\t'не требуются. Вики Грега лучше: «Из них $'...'это наиболее распространено и действует так же, как одинарные кавычки, за исключением того, что комбинации с обратным слэшем расширяются в соответствии со стандартом ANSI C».
Cristian Ciupitu
9
Оглядываясь назад, в $'\t'этом нет необходимости. awk понимает, что строка "\t"является символом табуляции
Гленн Джекман,
6
Авторы открытого исходного кода, прошу вас, не отправляйте такие вещи, как awk -F $'\t' 'BEGIN {OFS = FS} …'. Так и должно быть awk -v FS='\t' -v OFS='\t' '…'. Это может показаться педантичным, но непоследовательность увеличивает вероятность того, что более поздний участник внесет ошибку из-за неправильного понимания вашего кода.
Бруно Броноски
21

Убедитесь, что это действительно вкладки! В bash вы можете вставить вкладку, используяC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED
Махмуд Абделькадер
источник
9

Использование:

awk -v FS='\t' -v OFS='\t' ...

Пример из одного из моих скриптов .

Я использую FSи OFSпеременные для управления файлами зоны BIND, которые табуляцией:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Это простой и понятный способ сделать это.

Бруно Броноски
источник
5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'
Shantanuo
источник
-2

Это не должно работать?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
Асадз
источник