次のような大きな csv ファイル (Test.csv) があります。
1,2,3,A,5
1,2,3,B,5
1,2,3,E,5
1,2,3,D,5
1,2,3,Z,5
1,2,3,B,5
異なるファイル内の 4 列目の内容が同じ行を印刷したいのですが、実際には、同じ内容の行を 4 列目の内容という名前で新しい csv または txt ファイルに結合する必要があります。例:
出力:
ファイルA
1,2,3,A,5
1,2,3,A,5
1,2,3,A,5
ファイルB
1,2,3,B,5
1,2,3,B,5
入力ファイルが大きいため、この 4 番目の列にいくつの異なるパターンがあるかはわかりません。列 4 には単語のみが含まれ、他の列には単語と数字が含まれます。
経験がないので、同様の質問を調べて、次のコードも試してみました。
awk 'NR==FNR{a[$4]=NR; next} $NF in a {print > "outfile" a[$NF]}' Test.csv
しかし、何も機能しませんでした。誰か助けてくれませんか? よろしくお願いします。
答え1
これは、あらゆる UNIX ボックス上の任意のシェルで POSIX ソートと任意の awk を使用して効率的に動作します。
$ sort -t, -k4,4 test.csv |
awk -F, '$4!=prev{close(out); out="File"$4; prev=$4} {print > out}'
$ head -n 20 File*
==> FileA <==
1,2,3,A,5
==> FileB <==
1,2,3,B,5
1,2,3,B,5
==> FileD <==
1,2,3,D,5
==> FileE <==
1,2,3,E,5
==> FileZ <==
1,2,3,Z,5
注意すべき点:
- いくつかのawkでは出力リダイレクトの右側の式を括弧で囲む必要があり、
- いくつかのawkは、出力ファイルを閉じずに、出力ファイルが12個程度を超えると、開いているファイルを多く保持しようとすると失敗します。
- 複数の出力ファイルを開いたままにしておくことは、それが可能なすべてのawkでは非常に非効率的であり、
- これを考慮して出力ファイルを行ごとに閉じることは、すべての awk で非常に非効率的になります。
答え2
出力ファイル名のフィールドを使用するだけでよいはずです。簡単な解決策:
awk -F, '{print > ("file_" $4 ".csv")}' Test.csv
これは少なくとも GNU awk では動作しfile_A.csv、file_B.csvなどを作成します。これにより、すべての出力ファイルが開いたままになり、特にプロセスごとのオープン ファイル制限に達した場合は、出力ファイルが増えるほど速度が低下することに注意してください。
-F,フィールド区切り文字をカンマに設定します。
示されたスクリプトが何を実行するのかわかりません。
答え3
このようなもの:
$ awk -F, '{ print $0 >> "file-" $4 ".txt"; }' ./tmp.txt
@ilkkachu の回答にあるように、 flag は-Fフィールド区切り文字をデフォルトの空白文字からコンマに変更します。 が存在する場合にファイルを上書きしないように、>>の代わりに を使用する必要があります。>
答え4
パイソン
#!/usr/bin/python
uni=[]
k=open('file.txt','r')
for i in k:
g=i.split(",")[3].strip()
if g not in uni:
uni.append(g)
for m in uni:
f=open("{0}.txt".format(m),'w')
l=open('file.txt','r')
for d in l:
if m in d.split(",")[3].strip():
f.write(d)
awkではすでに最良の解決策が提供されているが、これは私の試みである
for i in `awk -F "," '{if(!seen[$4]++)print $4}' file.txt`; do awk -v i="$i" -F "," '$4==i{print $0}' file.txt >$i.txt; done


