Понимание того, как OFS работает в AWK - PullRequest
0 голосов
/ 27 апреля 2019

Это продолжение моего вопроса , чтобы понять больше об OFS в AWK.

Насколько я понимаю, установите его один раз в начале, и он будет использован в "Распечатать "для разделения полей.Однако, это не сработало, как ожидалось, как объяснено в моем первоначальном вопросе.

Мой файл: somebody.txt

LN_A,FN_A<aa@xyz.com>;
LN_B,FN_B<bb@xyz.com>;

Ожидаемый результат:

FN_A,LN_A,aa
FN_B,LN_B,bb 

Я пробовал следующее:

awk -F'[,<@]' -v OFS=',' '{print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' 'NF=3 {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' 'NF=3; {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' '{$1=$1} {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' '{$1=$1} {print $0}' someone.txt

Наконец, мне удалось получить требуемый вывод со следующим:

awk -F'[,<@]' '{print $2 "," $1 "," $3}' someone.txt

Ответы [ 3 ]

2 голосов
/ 27 апреля 2019

Рассмотрим следующие случаи:

a) $ echo '1 2 3' | awk '{print}'
1 2 3

b) $ echo '1 2 3' | awk '{print $1, $2, $3}'
1 2 3

c) $ echo '1 2 3' | awk -v OFS=',' '{print}'
1 2 3

d) $ echo '1 2 3' | awk -v OFS=',' '{print $1, $2, $3}'
1,2,3

e) $ echo '1 2 3' | awk -v OFS=',' '{$1=$1; print}'
1,2,3

Выше показано, как OFS используется в «b» и «d» (когда отдельные поля печатаются в списке через запятую) и в «e» (когда запись $ 0 восстанавливается в результате присвоения значения полю перед печатью записи).

Это только 2 раза, когда OFS используется неявно - при печати списка через запятуюзначений и при восстановлении записи.

Когда вы печатаете запись (например, print или print $0) как в «a» и «c» выше или печатаете любую другую строку , выне использует OFS .OFS, возможно, использовался ранее для восстановления записи, как указано выше в «e», но для печати всего, что не является разделенным запятыми списком, не используется OFS, он просто печатает любую старую строку, которая в данном случае просто стоит $ 0.

Примечание:

  1. Явное изменение поля восстанавливает $ 0 из существующих полей, используя OFS между полями, оно не делит $ 0 на поля снова, поэтому FS не используется в этом процессе.Таким образом, $ 1 = $ 1 или sub (/ 1 /, 2, $ 1) использует OFS, но не FS.
  2. Явное изменение $ 0 (т.е. неявно как результат 1 выше) делит $ 0 на поля с использованием FS в качестве разделителя, он никак не использует OFS.Таким образом, $ 0 = $ 0 или sub (/ 1 /, 2) использует FS, но не OFS.

Понимание того, как FS и OFS работают вместе и как они влияют на назначения полей и $ 0, очень важно.Если вы можете объяснить это поведение, тогда у вас это есть:

f) $ echo 'a b' | awk -v OFS=',' '{print NF, $0, $1, $2}'
2,a b,a,b

g) $ echo 'a b' | awk -v OFS=',' '{$1=$1; print NF, $0, $1, $2}'
2,a,b,a,b

h) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; print NF, $0, $1, $2}'
1,a,b,a,b,

i) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; print NF, $0, $1, $2}'
1,a,b,a,b,

j) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; $1=$1; print NF, $0, $1, $2}'
1,a,b,a,b,

k) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; $1=$1; $0=$0; print NF, $0, $1, $2}'
2,a,b,a,b

Если нет, то не стесняйтесь задавать вопросы.

1 голос
/ 27 апреля 2019

Поскольку я только что нашел неиспользованную копию Aho, Kernighan, Weinberger: Язык программирования AWK с 1988 года, я (t) перенесу вас к источнику (страницы 35-36):

" Переменные полей. Поля текущей входной строки называются $1, $2, до $NF; $0 относится ко всей строке. Поля имеют общие свойствадругие переменные - они могут использоваться в арифметических или строковых операциях и могут быть присвоены. - -

В поле можно назначить новую строку:

    BEGIN                          { FS = OFS = "\t" }
    $4 == "North America"          { $4 = "NA" }
    $4 == "South America"          { $4 = "SA" }
                                   { print }

В этой программедействие BEGIN устанавливает FS, переменную, которая управляет разделителем поля ввода, и OFS, разделитель поля вывода, как на вкладку. Оператор print в четвертой строке печатает значение $0после того, как оно было изменено предыдущими назначениями. Это важно: когда $0 изменяется при назначении или замене, $1, $2 и т. д., и NF будет пересчитано, также, когда один$1, $2 и т. д., изменено, $0 являетсяс использованием OFS для разделения полей."

1 голос
/ 27 апреля 2019

Это просто, вы установили OFS="," в начале вашего оператора awk, но вы просто печатаете поля (ПРИМЕЧАНИЕ: без редактирования строки ИЛИ без упоминания разделителя полей (с использованием запятой и т. Д.)) В этом случае OFS не появится, поэтому ваш вывод НЕ имеет ничего похожего на разделитель.

awk -F'[,<@]' -v OFS=',' '{print $2,$1,$3}' Input_fie

Если вы используете вышеупомянутую команду, где я упомянул , между полями печати, вы увидите, что вы получаете OFS сейчас, и вот как это работает.



Или, если вы хотите увидеть использование OFS, вы можете использовать это (хотя вышеприведенное решение ЛУЧШЕЕ, но для вашего понимания я также добавляю это).

awk -F'[,<@]' -v OFS=',' '{$0=$2 OFS $1 OFS $3} 1'  Input_file


Пример для понимания OFS путем печати целых строк: Давайте разберемся в этом более четко, напечатав всю строку с эффектом OFS and without OFS`.

Давайте запустим этот код:

awk -F'[,<@]' -v OFS=',' 'FNR==1{$1=$1} 1'  Input_file

Что происходит, когда есть номер строки 1, тогда я сбрасываю значение $1, как упомянуто выше, чтобы позволить OFS войти в изображение, чтобы появилось новое значение OFS (вне курса везде, где поле разделитель был выбран, он поместит туда значение OFS). Так что это будет сделано только для первой строки и REST строк ничего не должно происходить. Давайте посмотрим, какой выход выйдет сейчас?

LN_A,FN_A,aa,xyz.com>;
LN_B,FN_B<bb@xyz.com>;

Вы видите разницу? Видите, первая строка имеет , на выходе, а вторая строка печатает как есть, почему, потому что только в 1-й строке мы отредактировали первое поле, чтобы OFS вошло в изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...