
我有一個大的 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
我想列印第四列在不同文件中具有相同內容的行。實際上,我需要將這些具有相同內容的行加入到新的 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 列僅包含單字,其他列包含單字和/或數字。
由於我沒有經驗,我研究了類似的問題,甚至嘗試了以下程式碼:
awk 'NR==FNR{a[$4]=NR; next} $NF in a {print > "outfile" a[$NF]}' Test.csv
但沒有任何作用。有人可以幫我嗎?提前致謝。
答案1
這將在每個 UNIX 機器上的任何 shell 中使用 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
需要注意的一些事項:
- 有些 awks 需要在輸出重定向右側的表達式周圍放置括號,並且
- 如果您不關閉輸出文件,某些 awks 會失敗,因此一旦超過十幾個輸出文件,就會嘗試保留太多打開的文件,並且
- 在所有允許的 awks 中,保留多個開啟的輸出檔案效率非常低,且
- 在所有 awks 中,逐行關閉輸出檔來解決這個問題將非常低效。
答案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
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