HackWare.ru

awk и табуляция во вводимых и выводимых данных

Почему awk неправильно определяет границы данных, разделённых табуляцией

Следующая команда вместо ожидаемого третьего столбца вернёт пустой результат:

echo '1     2     3     4     5     6' | awk -F'\t' '{ print $3 }'

В команде вместо стандартного FS (Input field separator, разделитесь полей входных данных), которым по умолчанию является пробел, опцией -F'\t' установлен новый разделитесь, в качестве которого указан «\t», что означает символ табуляции.

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

То есть использовании опции -F не нужно в предыдущей команде:

echo '1     2     3     4     5     6' | awk '{ print $3 }'
3

Несмотря на то, что данные разделены несколькими пробелами, указывать это с опцией -F не нужно, поскольку она правильно истолковывает ввод. По умолчанию разделителем полей в awk служит один или больше пробелов (пробельные символы или символ табуляции), что соответствует [ \t]+ или если использовать posix классы [[:blank:]]+

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

echo '1	2	3	4' | awk '{ print $3 }'
3

В этом случае опция -F'\t' работает как и ожидается:

echo '1	2	3	4' | awk -F'\t' '{ print $3 }'
3

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

Чтобы проверить, какие именно непечатные символы присутствуют во вводимых данных, используйте cat -A. Например:

echo '1	2	3    4' | cat -A
1M-bM-^PM-^A^IM-oM-?M-=2^I3    4$

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

Следующая команда выведет третью и четвёртую колонку, разделяя их пробелом:

echo '1	2	3	4	5' | awk '{ print $3,$4 }'
3 4

Если вы хотите, чтобы выводимые данные разделялись табуляцией (или любым другим символом), то его нужно установить в качестве значения OFS (output field separator, разделитесь выходных полей). Например:

echo '1	2	3	4	5' | awk 'BEGIN {OFS="\t"}; { print $2,$3 }'
2	3

OFS вставляется между полями, перечисленными через запятую, то есть следующая команда не выведет табуляции между полями (и даже не выведет пробел):

echo '1	2	3	4	5' | awk 'BEGIN {OFS="\t"}; { print $2 $3 }'
23

Кроме изменения значения OFS (output field separator, разделитесь выходных полей) вы можете указать символ табуляции в шаблоне вывода. Например, следующая команда для разделения второго и третьего поля будет использовать стандартный OFS (то есть пробел), а между третьей и четвёртой колонкой будет вставлен знак табуляции:

echo '1	2	3	4	5' | awk '{ print $2,$3"\t"$4 }'
2 3	4

Смотрите также: Уроки по Awk

История обновлений

No update history yet.

Рекомендуется:
↑