Печать запятой, кроме последней строки в 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