Поведение разделителя полей Awk - PullRequest
5 голосов
/ 10 февраля 2011

Почему этот скрипт awk:

awk '{FS = "\t" ; print $1 " - " $2}' A.txt

с этим входным файлом A.txt

B A A1
C B A2
D A A3

выводит эти результаты

B - A
C B - A2
D A - A3

Обратите внимание, что между первым Bи A есть пробел, а не символ табуляции.Я дважды проверил это

Ответы [ 4 ]

7 голосов
/ 10 февраля 2011

Правильный путь:

BEGIN {FS = "\t"}
{ print $1 " - " $2}  

Вы устанавливаете FS слишком поздно (после разделения первой строки)

7 голосов
/ 10 февраля 2011

Я полагаю, это потому, что FS устанавливается в первом действии. До того, как будет выполнено первое действие, разделение первой строки уже выполнено, и в нем используется FS по умолчанию (пробел).

Таким образом, чтобы получить согласованность, вы должны вызвать awk с опцией -F.

2 голосов
/ 19 апреля 2012

Во-первых, вы меняете переменную FS в каждой строке;Вы, вероятно, намереваетесь изменить его только один раз.Кроме того, если вы хотите изменить FS, вы, вероятно, захотите изменить его, прежде чем какие-либо строки будут проанализированы.POSIX требует, чтобы любые изменения в FS влияли только на разбор строки next .(Многие реализации еще не соответствуют этому требованию и могут использовать измененное значение FS для текущей строки, если текущая строка еще не была проанализирована.) Чтобы решить обе эти проблемы, вы должны изменить FS следующим образом:

awk 'BEGIN { FS="\t" } {...}' A.txt

или это:

awk -v 'FS=\t' '{...}' A.txt

(Есть также форма, использующая -F '\t' вместо -v 'FS=\t', но некоторые реализации awk не будут соблюдать C-escape \t в прежней конструкции.)

Но обратите внимание, что FS управляет разбором входных данных, тогда как OFS управляет разбором выходных данных.Из твоего вопроса не понятно, чем ты хочешь заниматься.На первый взгляд, ваши входные данные не выглядят так, как будто в них есть какие-либо вкладки, поэтому вы, вероятно, захотите оставить для FS значение по умолчанию "".

Если вы хотите изменить вывод форматирование, вы можете установить OFS в «\ t» любым из способов, которые мы только что описали для FS.Однако не совсем понятно, чего вы хотите, поскольку вы не используете OFS в тестовом сценарии.Когда вы говорите:

print $1 " - " $2

, вы печатаете один аргумент, который представляет собой конкатенацию $ 1 и «-» и $ 2.Чтобы использовать OFS, вам нужно вывести несколько аргументов, которые будут разделены запятой - например, вот так:

print $1, $2

Озадаченный, я снова смотрю на пример данных и выводВы представляете.Возможно, ваши примерные данные действительно имеют формат: B<space>A<tab>A1, и, возможно, вы do намереваетесь установить FS, чтобы захватить B<space>A за 1 доллар и A1 за 2 доллара.Если это так, тогда просто убедитесь, что FS установлен в нужное время, прежде чем начнется какая-либо обработка строки.Тогда ваш скрипт должен работать независимо от того, какую реализацию awk вы используете.

0 голосов
/ 10 февраля 2011

если вы не ставите пробел между ними, awk просто объединяет строку.

измените команду на

print $1, " - ", $2

также вы, вероятно, захотите установить OFS для вывода

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