我有一个包含许多列的文件,我只需要其中两列。我正在使用
获取我需要的列cut -f 2-3 -d, file1.csv > file2.csv
我遇到的问题是,第一列是ID,一旦超过999
,它就变为1,000
,因此现在它被视为一个额外的列。我无法摆脱所有逗号,因为我需要它们来分隔数据。有没有办法使用sed
删除仅显示在0-9
之间的逗号?
答案 0 :(得分:1)
我使用真正的CSV解析器,并从行尾向后计数:
ruby -rcsv -ne '
row = $_.parse_csv
puts row[-5..-4].to_csv :force_quotes => true
' <<END
999,"someone@example.com","Doe, John","Doe","555-1212","address"
1,234,"email@email.com","name","lastname","phone","address"
END
"someone@example.com","Doe, John"
"email@email.com","name"
答案 1 :(得分:0)
根据您的评论,听起来令牌之间有逗号和空格(', '
)模式。
如果是这种情况,您可以使用sed轻松完成此操作。策略是首先将所有出现的,
替换为一些唯一的字符序列(如||
}。
's:, :||:g'
从那里你可以删除所有逗号:
's:,::g'
最后,再次用逗号空格替换双管道。
's:||:, :g'
将其置于一个陈述中:
sed -i -e 's:, :||:g;s:,::g;s:||:, :g' your_odd_file.csv
在购买之前尝试的命令行示例:
bash$ sed -e 's:, :||:g;s:,::g;s:||:, :g' <<< "1,200,000, hello world, 123,456"
1200000, hello world, 123456
如果您处于CSV中字段之间不空间的不幸情况 - 您可以尝试伪造它&#39;通过检测数据类型的变化 - 比如有一个数字字段后跟一个文本字段。
's:,\([^0-9]\):, \1:g' # numeric followed by non-numeric
's:\([^0-9]\),:\1, :g' # non-numeric field followed by something (anything)
你可以把这一切都放在一个声明中,但是你冒险进入危险的水域 - 这肯定是一次性的解决方案,应该用大量的盐。
sed -e 's:,\([^0-9]\):, \1:g;s:\([^0-9]\),:\1, :g' \
-e 's:, :||:g;s:,::g;s:||:, :g' file1.csv > file2.csv
另一个例子:
bash$ sed -e 's:,\([^0-9]\):, \1:g;s:\([^0-9]\),:\1, :g' \
-e 's:, :||:g;s:,::g;s:||:, :g' <<< "1,200,000,hello world,123,456"
1200000, hello world, 123456
答案 2 :(得分:0)
这适用于评论中的示例:
awk -F'"?,"' '{print $2, $3}' file
字段分隔符为零或一"
后跟,"
。这意味着第一个数字中的逗号不计算在内。
要使用逗号而不是空格分隔两个字段,您可以像这样更改OFS
变量:
awk -F'"?,"' -v OFS=',' '{print $2, $3}' file
或者像这样:
awk -F'"?,"' 'BEGIN{OFS=","}{print $2, $3}' file
或者,如果您也想要引号,可以使用printf
:
awk -F'"?,"' '{printf "\"%s\",\"%s\"\n", $2, $3}' file