【问题标题】:Split CSV file according to value in a column, but only keep 1 column and save as TXT根据列中的值拆分CSV文件,但只保留1列并另存为TXT
【发布时间】:2020-08-21 01:15:35
【问题描述】:

我有一个两列电子表格(以 CSV 格式保存),如下所示:

COLUMN 1,COLUMN 2
innovation,3-Entrepreneurship
countless,
innocent,2-Police
toilet handle,2-Bathroom
née dresses,3-Companies
odorless,2-Sense of Smell
old ideas,3-Entrepreneurship
new income streams,3-Entrepreneurship
Zoë’s food store,3-Companies
many,
crime,2-Police
bath room,2-Bathroom
ring,
móvíl résumés,3-Companies
musty smell,2-Sense of Smell
good publicity guru,3-Entrepreneurship
Señor,3-Companies

完整的电子表格有 6000 行(以 CSV 格式保存,用逗号分隔两列)。它不仅包含此处列出的第 2 列类别。

如图所示,第 1 列的某些条目由两个或三个单词组成,由空格分隔。他们还使用撇号和重音字符(它们出现在多个类别中,而不仅仅是标题为 3-Companies 的类别)。

您可以下载完整电子表格的示例here

我想按第 2 列中的值将 CSV 文件拆分为单独的 TXT 文件。单独的文件将不再是电子表格,而只是单词列表。

例如拆分后

在文件 3-Entrepreneurship.txt

innovation
old ideas
new income streams
good publicity guru

在文件 2-Bathroom.txt

toilet handle
bath room

在文件 2-Police.txt

innocent
crime

在文件 2-Sense of Smell.txt

odorless
musty smell

在文件 3-Companies.txt

née dresses
Zoë’s food store
móvíl résumés
Señor

这只是一个示例。完整文件有超过 5 个类别(在第 2 列中),因此拆分后的文件将超过 5 个。


到目前为止,这是我的代码:

awk -F "," '{print $0 >> ($2 ".txt"); close($2 ".txt")}' test.csv

它有效,但有几个问题:

  1. 文件名以问号结尾。 例如。 2-Police?.txt3-Entrepreneurship?.txt

  2. 文件以两列打印出来。

例如,在 3-Entrepreneurship.txt 中包含以下数据:

innovation  3-Entrepreneurship
ideas       3-Entrepreneurship
income      3-Entrepreneurship
publicity   3-Entrepreneurship

【问题讨论】:

  • 您应该打印第一个字段,而不是整行:print $1 >>。您的第二个问题可能是由于输入文件中的 DOS 行结尾 ("\r\n")。你可能想用awk -v RS='\r\n'打电话给awk
  • 我不知道。您的 awk 电话在我的盒子上运行良好。但请注意,只有一个字段的行将被收集到一个名为 .csv 的文件中。
  • 您在命令行中有拼写错误。应该是awk -v RS='\r\n' -v ORS='\r'...
  • @M.NejatAydin 在 RS 中使用超过 1 个字符是每个 POSIX 未定义的行为,因此设置 RS='\r\n' 将在 GNU awk 和其他一些中执行您想要的操作,但在其他一些中它仍然会表现好像您写了RS='\r',这可能是OP 在每条记录之前看到空白行的原因,它是应该在每行末尾的\n 现在被放在下一行的开头。跨度>
  • @big_smile wrt I am using Mac OS 10.14.6 if that makes a difference 是的。 MacOS 上的默认 awk 是 BSD awk,它只需要单字符 RS 值并将任何多字符 RS 截断为第一个字符,因此会将 RS='\r\n' 视为您编写 RS='\r'。如果您安装 GNU awk,那么您可以使用多字符 RS 和大量其他非常有用的扩展。

标签: csv awk


【解决方案1】:
tail -n +2 file |
sort -t',' -k2 |
awk -F',' '$2~/^[[:space:]]*$/{next} {sub(/\r$/,"")} $2!=prev{close(out); out=$2".txt"; prev=$2} {print $1 > out}'

为了提高效率,我们首先对数据进行排序,这样 awk 就不必逐行打开/关闭文件,而是只对每个唯一的 $2 值执行一次。

这是脚本的工作:

$ ls
file

$ cat file
COLUMN 1,COLUMN 2
innovation,3-Entrepreneurship
countless,
innocent,2-Police
toilet handle,2-Bathroom
née dresses,3-Companies
odorless,2-Sense of Smell
old ideas,3-Entrepreneurship
new income streams,3-Entrepreneurship
Zoë’s food store,3-Companies
many,
crime,2-Police
bath room,2-Bathroom
ring,
móvíl résumés,3-Companies
musty smell,2-Sense of Smell
good publicity guru,3-Entrepreneurship
Señor,3-Companies

.

$ tail -n +2 file | sort -t',' -k2 | awk -F',' '$2~/^[[:space:]]*$/{next} {sub(/\r$/,"")} $2!=prev{close(out); out=$2".txt"; prev=$2} {print $1 > out}'

.

$ ls
 2-Bathroom.txt   2-Police.txt  '2-Sense of Smell.txt'   3-Companies.txt   3-Entrepreneurship.txt   file

$ head -n 50 *.txt
==> 2-Bathroom.txt <==
bath room
toilet handle

==> 2-Police.txt <==
crime
innocent

==> 2-Sense of Smell.txt <==
musty smell
odorless

==> 3-Companies.txt <==
móvíl résumés
née dresses
Señor
Zoë’s food store

==> 3-Entrepreneurship.txt <==
good publicity guru
innovation
new income streams
old ideas

【讨论】:

  • 谢谢我更新了开场白。感谢您的帮助和耐心!
  • 谢谢,太好了!我注意到它在每个文件的末尾添加了一个空行。有什么办法可以避免吗?
  • 不,正如您在我的回答中的head 输出中看到的那样,它不会这样做。
【解决方案2】:

你们很亲密。

首先,似乎不应该将第 2 列中没有值的单词写入文件。如果是这样,请为您的操作添加测试。测试可以只是$2,如果$2 为空,它将跳过{ ... } 内的操作。

其次,如果您只想要单词,则只将 col 1 写入文件 - 而不是 $0 中的整行

使用您的示例,它不是, 分隔的,您可以这样做:

awk '$2 {print $1 >> ($2 ".txt"); close($2 ".txt")}' file

请务必删除 .txt 文件或在空目录中运行,因为如果文件已存在,则会附加这些文件。

生产:

2-Bathroom.txt:
toilet
bath

2-Police.txt:
innocent
crime

2-Sense.txt:
odorless
musty

3-Entrepreneurship.txt:
innovation
ideas
income
publicity

【讨论】:

  • 这类作品,除了,3-Entrepreneurship.txt,被分成了两个文件。第一个文件包含“创新”、“想法”和“收入”,而第二个文件(,3-Entrepreneurship?.txt)只包含“宣传”。此外,所有文件名前面都有一个逗号。
猜你喜欢
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2020-05-20
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多