Как напечатать поле из файла, разделенного каналом?
Вопрос
У меня есть файл с полями, разделенными символами канала, и я хочу напечатать только второе поле. Эта попытка не удалась:
$ cat file | awk -F| '{print $2}'
awk: syntax error near line 1
awk: bailing out near line 1
bash: {print $2}: command not found
Есть ли способ сделать это?
Решение
Ключевым моментом здесь является то, что символ канала (|
) должен быть экранирован в оболочку. Используйте & Quot; \|
& Quot; или " '|'
" чтобы защитить его от вмешательства оболочки и разрешить его передачу в командную строку awk
.
Читая комментарии, я вижу, что оригинальный постер представляет упрощенную версию исходной задачи, которая включала фильтрацию file
перед выбором и печатью полей. Был использован проход через grep
, и результат был передан в awk для выбора поля. Это объясняет совершенно ненужное cat file
, которое появляется в вопросе (оно заменяет grep <pattern> file
).
Хорошо, это сработает. Однако awk в значительной степени сам по себе является средством сопоставления с образцом, и ему можно доверять, чтобы находить и обрабатывать совпадающие строки, не вызывая /<pattern>/
. Используйте что-то вроде:
awk -F\| '/<pattern>/{print $2;}{next;}' file
Бит <pattern>
указывает {next;}
выполнить действие, которое следует за строками, которые соответствуют <=>.
Потерянный вид <=> - это действие по умолчанию, пропускающее следующую строку ввода. В этом нет необходимости, но у меня такая привычка давно ...
Другие советы
Или просто используйте одну команду:
cut -d '|' -f FIELDNUMBER
Символ канала должен быть экранирован, чтобы оболочка не интерпретировала его. Простое решение:
$ awk -F\| '{print $2}' file
Другой вариант - процитировать персонажа:
$ awk -F'|' '{print $2}' file
А 'file' не содержит символов канала, поэтому ничего не печатает. Вы должны либо использовать 'cat file', либо просто перечислить файл после программы awk.