Распечатать все поля с AWK, разделенными OFS

Есть ли способ распечатать все записи, разделенные OFS, без ввода номера каждого столбца.

#Desired style of syntax, undesired result
[kbrandt@glade: ~] echo "1 2 3 4" | gawk 'BEGIN { OFS=" :-( "}; {print $0}'        
1 2 3 4

#Desired result, undesired syntax
[kbrandt@glade: ~] echo "1 2 3 4" | gawk 'BEGIN { OFS=" :-) "}; {print $1,$2,$3,$4}'
1 :-) 2 :-) 3 :-) 4

person Kyle Brandt    schedule 04.12.2012    source источник


Ответы (2)


Это вариация первого стиля:

echo "1 2 3 4" | gawk 'BEGIN { OFS=" :-( "}; {$1=$1; print $0}'

Результаты:

1 :-( 2 :-( 3 :-( 4

Объяснение:

$1=$1 — перестроить запись, используя текущую OFS (вы также можете увидеть http://www.gnu.org/software/gawk/manual/gawk.html#Changing-Fields)

Обновлять:

(предложено @EdMorton и @steve) Это более короткая эквивалентная версия команды awk, которая устанавливает OFS в командной строке и использует print $0 в качестве действия по умолчанию:

awk -v OFS=" :-( " '{$1=$1}1'
person German Garcia    schedule 04.12.2012
comment
Примечание @steve: было одно редактирование, в котором блок {$1=$1; print $0} был заменен только на $1=$1. Это потерпит неудачу для $1 == 0. - person German Garcia; 04.12.2012
comment
@EdMorton, это вполне допустимая альтернатива (awk -v OFS=" :-( " '{$1=$1}1'. Мне все еще нравится первая версия, потому что она так похожа на OP (и я не вижу явного преимущества одного над другим, возможно, в основном это вопрос стиля) - person German Garcia; 05.12.2012
comment
@GermanGarcia: Разве это не точное редактирование, которое я сделал? Лично я думаю, что awk -v OFS=" :-( " '{$1=$1}1 понятнее, но единственная причина, по которой я решил отредактировать, заключалась в том, что пользователям на самом деле не понадобится конкретно GNU awk. Команда должна работать и для других awks. Если бы мы пытались сделать вещи короче, мы могли бы пойти дальше: awk '{$1=$1}1' OFS=" :-( ". ХТН. - person Steve; 05.12.2012
comment
@GermanGarcia В этом случае я немного предпочитаю более краткую версию, поскольку она усиливает концепцию использования -v для присвоения начальных значений переменным и печати $0 в качестве действия по умолчанию, и это обе вещи, которые, если вы опытны, у вас будет нет проблем с пониманием и, вероятно, естественно использовать, и если вы неопытны, вам действительно нужно ознакомиться с как можно скорее, поэтому ИМХО это имело преимущества как для опытных, так и для неопытных пользователей awk. Впрочем, ничего страшного. - person Ed Morton; 05.12.2012
comment
Вы можете покончить с блоком и сделать на один символ короче с немного более неясным: $1=$1;1. - person Thor; 05.12.2012
comment
@steve Нет, это было не твое точное редактирование. Вы можете увидеть свои изменения здесь: stackoverflow.com/revisions/13705660/2 (используется только условие $1=$1, оставляя часть действия пуста, но это создает проблему ложного условия для $1 == 0). Что касается более краткой версии, я добавлю ее через мгновение. Спасибо за ваши комментарии. - person German Garcia; 05.12.2012
comment
@EdMorton Я обновил ответ, включив в него более краткую версию, предложенную вами и Стивом, чтобы учесть эти концепции. - person German Garcia; 05.12.2012
comment
@Thor $1=$1;1 дважды напечатает каждую строку, которая имеет ненулевое/нулевое значение $1, что, вероятно, нежелательно. Вы могли бы сделать $1=$1,1, но, как мы недавно обнаружили, никто не знает, что это значит, без какого-либо расследования, поэтому этого следует избегать :-). - person Ed Morton; 06.12.2012
comment
@GermanGarcia: Кажется, ты был прав! Я, должно быть, забыл добавить 1 в конце. Я виню в том, что не сплю... но ведь нет оправдания? - person Steve; 06.12.2012
comment
@EdMorton: дох, проигнорируй мое предложение. Кстати, $1=$1,1 здесь не работает с gawk, он оценивается как false. Во всяком случае, самая краткая понятная версия уже опубликована. - person Thor; 06.12.2012
comment
@steve Я всегда оставляю себе еще одно оправдание на всякий случай :) С уважением - person German Garcia; 07.12.2012
comment
По какой-то причине это решение печатает два OFS после первой записи. (Я могу переместить удвоенный OFS, если заменю $1=$1, скажем, $10=$10). Любое объяснение? Я могу избавиться от него, если сделаю {$NF=$NF}1 - person davemyron; 04.06.2015
comment
@davemyron Я не смог воспроизвести упомянутое вами поведение (пробовал оригинальный awk, mawk и gawk). Какую версию awk вы используете? Можете ли вы привести небольшой пример? - person German Garcia; 05.06.2015
comment
@GermanGarcia Я столкнулся с проблемой при использовании FPAT для значений, разделенных запятыми: awk -v FPAT='[^,]*|"[^"]*"' -v OFS='|' '{$1=$1}1' <(echo "comma,separated,values") приводит к comma||separated|values - person davemyron; 10.06.2015
comment
@davemyron Я пробовал ваш образец, и он действительно печатает эти два OFS после первого поля (точно после поля $N, за исключением случаев, когда N == NF, как вы уже упоминали) при использовании FPAT. Я не знаю, почему gawk действует таким образом (ИМХО, это похоже на ошибку, и использование $NF=$NF, как вы предлагаете, может действовать как обходной путь). Кроме того, кажется, что это работает нормально, если вы используете [^,]+ вместо [^,]* ..но теперь у вас не может быть пустых полей внутри запятых - person German Garcia; 25.06.2015
comment
Поскольку вопрос заключается в том, что OFS = "something" действует в выходных данных, и ничего не предполагает об изменении других системных переменных, я хотел бы добавить, что если установить FS = "\n" также в правиле BEGIN, $1 = $1 явно недостаточно, поскольку это также необходимо установить RS = "" в правиле BEGIN. (Действительно, я столкнулся с этим вопросом, пытаясь использовать awk для объединения всех строк файла, поскольку простая установка FS = "\n" и OFS = " ", похоже, не сработала.) - person Enlico; 15.04.2018

Эквивалент СЭД:

$ echo "1 2 3 4" | sed 's/ /:-)/g'

Вот еще вариант с awk:

$ echo "1 2 3 4" | awk '{ gsub(/\s/, ":-)")}1' 
person Fred Hicks    schedule 21.09.2014
comment
Добро пожаловать в СО! Вопрос касается конкретно awk. Так что ответ с использованием sed здесь неуместен. - person cfi; 22.09.2014
comment
Я думаю, что вы должны прочитать sed 's/ / :-) /g', если вы заметили, что в ОП был пробел вокруг смайлика в OFS. - person v010dya; 09.10.2015