Выход Awk удаляет запятую - PullRequest
2 голосов
/ 02 мая 2020

Если у меня есть следующий CSV-файл с именем mycsv.txt:

0123, fred, 012345, end
023, smith, 012, end

и я применяю эту команду awk:

awk '{$1=sprintf("%05d", $1);$3=sprintf("%08d", $3)}1' mycsv.txt 

Я получаю такой вывод:

00123 fred, 00012345 end
00023 smith, 00000012 end

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

Ответы [ 3 ]

1 голос
/ 02 мая 2020

Не могли бы вы попробовать следующее.

awk 'BEGIN{FS=", ";OFS=","} {$1=sprintf("%05d", $1);$3=sprintf("%08d", $3)}1' Input_file

Выше будет напечатан разделитель поля вывода как ,, если вы хотите иметь ,, затем установите OFS как OFS=", ".

Вывод будет следующим:

00123,fred,00012345,end
00023,smith,00000012,end

Объяснение: Добавление подробного пояснения к вышеуказанному коду.

awk '                         ##Starting awk program from here.
BEGIN{                        ##Starting BEGIN section of this awk program from here.
  FS=", "                     ##Setting field separator as comma space here.
  OFS=","                     ##Setting OFS(output field separator) as comma here.
}
{
  $1=sprintf("%05d", $1)      ##Setting 1st field of value with sprintf value with 5 zeroes before 1st field value.
  $3=sprintf("%08d", $3)      ##Setting 3rd field of value with sprintf value with 5 zeroes before 3rd field value.
}
1                             ##Mentioning 1 will print current line here.
' Input_file                  ##Mentioning Input_file name here.
1 голос
/ 02 мая 2020

Происходит 2 вещи:

  1. Если вы не укажете разделитель полей (например, FS=","), то awk будет использовать цепочки пробелов, поэтому ваше первое поле, $1, вашей первой строки ввода будет 0123,, а не 0123 и
  2. Когда вы выполняете операцию нумерации c над строкой, awk удаляет все не-цифры с правой стороны этой строки и начальных нулей с левой стороны, чтобы превратить его в число, тогда 0123, становится 123000173foo становится 173).

То есть $1 равно 0123, и, следовательно:

sprintf("%05d", $1) = sprintf("%05d", "0123,") = sprintf("%05d", "123") = 00123

, который при присвоении этого результата $1 заменяет 0123, на 00123, следовательно, исчезает ,.

Это то, что вы действительно хотели:

awk '
    BEGIN { FS="[[:space:]]*,[[:space:]]*"; OFS=", " }
    { $1=sprintf("%05d", $1); $3=sprintf("%08d", $3) }
1' mycsv.txt

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

1 голос
/ 02 мая 2020

Поля первой строки: 0123,, fred,, 012345, и end. Вы изменили первое и третье на 00123 и 00012345 без запятой. Вот что печатает awk.

Вы имеете в виду:

awk '{$1=sprintf("%05d,", $1);$3=sprintf("%08d,", $3)}1' mycsv.txt

Вывод:

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