Печать запятой, кроме последней строки в Awk

У меня есть следующий script

awk '{printf "%s", $1"-"$2", "}' $a >> positions;

где $a хранится имя файла. Я фактически пишу несколько значений столбцов в одну строку. Однако я хотел бы напечатать запятую только в том случае, если я не на последней строке.

Ответ 1

Я бы сделал это, найдя количество строк перед запуском script, например. с coreutils и bash:

awk -v nlines=$(wc -l < $a) '{printf "%s", $1"-"$2} NR != nlines { printf ", " }' $a >>positions

Если ваш файл имеет только 2 столбца, также работает следующая альтернатива coreutils. Пример данных:

paste <(seq 5) <(seq 5 -1 1) | tee testfile

Вывод:

1   5
2   4
3   3
4   2
5   1

Теперь, заменяя вкладки на новые строки, paste легко собирает дату в желаемый формат:

 <testfile tr '\t' '\n' | paste -sd-,

Вывод:

1-5,2-4,3-3,4-2,5-1

Ответ 2

Однопроходный подход:

cat "$a" | # look, I can use this in a pipeline! 
  awk 'NR > 1 { printf(", ") } { printf("%s-%s", $1, $2) }'

Обратите внимание, что я также упростил форматирование строк.

Ответ 3

Наслаждайтесь этим:

awk '{printf t $1"-"$2} {t=", "}' $a >> positions

Yeh, выглядит на первый взгляд немного сложнее. Поэтому я объясню, прежде всего, чтобы изменить ясность printf на print:

awk '{print t $1"-"$2} {t=", "}' file

и посмотрите, что он делает, например, для файла с этим простым контентом:

1 A
2 B
3 C
4 D

чтобы он произвел следующее:

 1-A
 , 2-B
 , 3-C
 , 4-D

Трюк - это предыдущая переменная t, которая пуста в начале. Переменная будет установлена ​​{t=...} только на следующем этапе обработки после того, как она будет показана {print t ...}. Поэтому, если мы продолжаем итерацию (awk), мы получим желаемую последовательность.

Ответ 4

Здесь лучший способ, не прибегая к coreutils:

awk 'FNR==NR { c++; next } { ORS = (FNR==c ? "\n" : ", "); print $1, $2 }' OFS="-" file file

Ответ 5

awk '{a[NR]=$1"-"$2;next}END{for(i=1;i<NR;i++){print a[i]", " }}' $a > positions