изменение содержимого столбца без разрушения форматирования - PullRequest
1 голос
/ 02 июля 2010

$ echo "ab" |awk '{print $ 0;$ 1 = "1";print $ 0} 'ab 1 b

Я хотел бы получить форматированный вывод, подобный этому:

 a       b
 1       b

Есть ли простой способ сделать это (без изменений IFS, OFS)?Я изменяю столбцы в большой таблице, а потом это выглядит некрасиво.Я не хочу переформатировать каждый столбец.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 02 июля 2010

Один возможный ответ (при условии фиксированного числа столбцов):

echo "a       b" | awk '{print $0; $1="1"; printf("%s\t%s\n", $1, $2)}'

Другой возможный ответ (при условии, что у вас нет веской причины избегать изменения OFS, поскольку, как вы знаете, это всеТОЧКА наличия одного!):

echo "a       b" | awk 'BEGIN { OFS="\t" } {print $0; $1="1"; print $0}'

Этот второй имеет преимущество работы независимо от того, сколько столбцов имеет ваш текстовый файл.


Отредактировано, чтобы добавить:

Чтобы объяснить, почему я думаю, что ваше отвращение к использованию OFS является странным, просто причина того, что вы получаете такое изменение форматирования, - , потому что от OFS.Разделитель выходного поля (OFS) по умолчанию представляет собой один пробел.Когда вы печатали $ 0 в первый раз, вы не вносили никаких изменений, поэтому $ 0 была неизменной линией.Изменяя одну из записей, вы заставили Awk пересмотреть строку, собрав $ 0 из отдельных полей.Разобрав это, конечно, Awk вставил OFS между полями.Потому что это то, что он должен делать.Цитата из соответствующей страницы руководства (man gawk):

Присвоение значения существующему полю приводит к перестроению всей записи при ссылке на $0.Точно так же присвоение значения $0 вызывает повторную разбиение записи, создавая новые значения для полей.

Теперь я согласен, что есть некоторая несогласованность между наличием первого отпечатка и второгоотноситься к полям по-разному, но это так, как язык.OFS не вставляется до тех пор, пока вы фактически не измените строку, и он на самом деле не вычислит поля, не перестроит и т. Д.Посмотрите на это:

$ awk 'BEGIN { printf("|%s|\n", OFS) }'
| |
$ awk 'BEGIN { OFS="\t" ; printf("|%s|\n", OFS) }'
|   |
$ 

Стало ли яснее поведение Awk в вашем первом примере, а также понимание того, зачем вам на самом деле нужен этот OFS или printf или тому подобное?

2 голосов
/ 02 июля 2010

Вероятно, вам лучше всего постобработать вывод. Возможно, что-то так просто, как:

$ ... | awk ... | column -t

будет работать. (Если «Я не хочу форматировать каждый столбец» означает «Я не хочу переформатировать каждую строку», например «Я не хочу публиковать процесс». В этом случае я бы спросил: «Почему нет? «)

1 голос
/ 03 июля 2010

Вы также можете использовать подстановку

$ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a       b
1       b
...