次の大きな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
これは、POSIX シーケンスと awk を使用するすべての UNIX システムのすべてのシェルで効率的に動作します。
$ 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
注意事項:
- 一部のawksでは、出力リダイレクトの右側の式の周りに括弧が必要です。
- 出力ファイルを閉じないと、一部のawksが失敗するため、12個以上の出力ファイルを取得すると、あまりにも多くの開いているファイルを保持しようとします。
- 許可されているすべてのawksで複数のオープン出力ファイルを維持することは非常に非効率的です
- すべてのawksでこの問題を解決するために、出力ファイルを1行ずつ閉じるのは非常に非効率的です。
答え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の答えで述べたように、フラグはフィールド-F
区切り文字をデフォルトの空白文字からコンマに変更することです。ファイルが存在する場合は、上書きしないように>>
代わりに使用する必要があります。>
答え4
Python
#!/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