我有一个大的 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