CSV数据格式
1st Format
name,email,mobile,email
a,a@test.com,1234567890,a@test.com
2nd Format
name,email,"mobile,number",email
a,a@test.com,1234567890,a@test.com
3rd Format
name,email,"mobile number",email
a,a@test.com,1234567890,a@test.com
在我上面的数据格式中,电子邮件的标题是重复的,所以我只想保留电子邮件的第一列值,第二个带标题的电子邮件数据应该从文件中删除。
我已经把它绑住了;s 工作不正常
awk -F'","' 'NR==1{for(i=1;i<=NF;i++)if(!($i in v)){ v[$i];t[i]}}{s=""; for(i=1;i<=NF;i++)if(i in t)s=s sprintf("%s,",$i);if(s){sub(/,$/,"",s);print s}} ' input.csv > output.csv
请建议相同的脚本命令
Awk可能不是操作CSV文件最实用的工具。还有很多其他的。
这里有几个例子,你的数据
-
csvtool(
sudo apt install csvtool
(
$ for f in [123].csv; do echo $f; csvtool col 1-3 "$f"; echo; done
1.csv
name,email,mobile
a,a@test.com,1234567890
2.csv
name,email,"mobile,number"
a,a@test.com,1234567890
3.csv
name,email,mobile number
a,a@test.com,1234567890
- csvcut(
sudo apt install csvkit
(
$ for f in [123].csv; do echo $f; csvcut -C 4 "$f"; echo; done
1.csv
name,email,mobile
a,a@test.com,1234567890
2.csv
name,email,"mobile,number"
a,a@test.com,1234567890
3.csv
name,email,mobile number
a,a@test.com,1234567890
- Perl的文本::CSV(
sudo apt install libtext-csv-perl
(
(这可能更适合更复杂的需求,并且应该在可读性更强的脚本文件中(
$ for f in [123].csv; do echo $f; perl -MText::CSV -lne 'BEGIN{$csv=Text::CSV_XS->new()} if ($csv->parse($_)) {$csv->print(*STDOUT, [ ($csv->fields)[0..2] ]);}' "$f"; echo; done
1.csv
name,email,mobile
a,a@test.com,1234567890
2.csv
name,email,mobile,number
a,a@test.com,1234567890
3.csv
name,email,mobile number
a,a@test.com,1234567890
如果您的CSV格式良好,请尝试
sed 's/^("([^"]|"")*"|[^",]*),("([^"]|"")*"|[^",]*),("([^"]|"")*"|[^",]*),("([^"]|"")*"|[^",]*)$/1,3,5/'
演示:https://ideone.com/7xKlGU
正则表达式不是特别优雅,但应该直接工作。"([^"]|"")*"
匹配引用的字段,[^",]*
匹配未引用的字段。这假设一个字段的全部被引用,或者根本不被引用,并且转义机制是将应该是字面的双引号加倍,这是大多数常见CSV方言中的惯例。