13

次のスクリプトがあります

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

どこ$aにファイルの名前を格納します。私は実際に複数の列の値を 1 つの行に書き込んでいます。ただし、最後の行にない場合にのみコンマを出力したいと思います。

4

6 に答える 6

22

シングル パス アプローチ:

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

文字列のフォーマットも単純化したことに注意してください。

于 2013-01-25T09:24:16.920 に答える
13

これをお楽しみください:

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

ええ、一見すると少しトリッキーに見えます。まず、わかりやすく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反復を続けると、目的のシーケンスが得られます。

于 2014-11-18T10:58:20.820 に答える
6

たとえば、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
于 2013-01-25T08:26:33.003 に答える
4

awk の ORS と OFS がこれを処理する合理的な方法だと思うかもしれません。

$ awk '{print $1,$2}' OFS="-" ORS=", " input.txt

ただし、入力の最後の行に改行が含まれているため、これは最終的な ORS になります。改行はレコード区切りであるため、awk の観点からは、入力に空の最後のレコードがあります。ちょっとしたハッカーでこれを回避することはできますが、結果として複雑になるため、ワンライナーの優雅さが失われます。

これが私の見解です。「複数の列の値を書き込んでいる」と言っているので、ORS と OFS をいじると問題が発生する可能性があります。したがって、書式設定だけで目的の出力を完全に実現できます。

$ cat input.txt
3 2
5 4
1 8
$ awk '{printf "%s%d-%d",t,$1,$2; t=", "} END{print ""}' input.txt
3-2, 5-4, 1-8

これは、Michael と rook のシングル パス アプローチに似ていますが、シングル パスをprintf使用し、フォーマットにフォーマット文字列を正しく使用しています。

これは、Michael のソリューションよりもわずかに優れたパフォーマンスを発揮する可能性があります。これは、割り当てがテストよりも CPU を必要としないためであり、ファイルを一度だけ読み取る必要があるため、どのマルチパス ソリューションよりも明らかに優れています。

于 2018-03-10T18:47:29.867 に答える
1

coreutils に頼らない、より良い方法を次に示します。

awk 'FNR==NR { c++; next } { ORS = (FNR==c ? "\n" : ", "); print $1, $2 }' OFS="-" file file
于 2013-01-25T08:58:37.820 に答える
0
awk '{a[NR]=$1"-"$2;next}END{for(i=1;i<NR;i++){print a[i]", " }}' $a > positions
于 2013-01-25T09:26:01.467 に答える