pit*_*las 11 shell sed awk text-processing
我有一个 .csv 文件(在 Mac 上),它有一堆空行,例如:
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum ","2","3","4"
Run Code Online (Sandbox Code Playgroud)
我想转换为:
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
Run Code Online (Sandbox Code Playgroud)
我知道必须有一个单行但我不知道 awk 或 sed。任何提示非常感谢!
der*_*ert 11
您可以使用 grep 的-v
(反转匹配)模式来执行此操作:
grep -v '^$' old-file.csv > new-file.csv
Run Code Online (Sandbox Code Playgroud)
请注意,由于 shell 重定向的工作方式,这些文件必须是不同的文件。在读取输入文件之前打开(并清空)输出文件。如果您有 moreutils(在 Mac OS X 上不是默认设置),您可以使用它sponge
来解决这个问题:
grep -v '^$' file.csv | sponge file.csv
Run Code Online (Sandbox Code Playgroud)
但是,当然,如果出现问题,您将很难返回。
如果您的“空白行”实际上可能包含空格(听起来确实如此),那么您可以改用它:
egrep -v '^[[:space:]]*$' old-file.csv > new-file.csv
Run Code Online (Sandbox Code Playgroud)
这将忽略空行以及仅包含空格的行。您当然可以对其进行相同的sponge
转换。
要删除空行,就地,使用 ksh93:
sed '/./!d' file 1<>; file
Run Code Online (Sandbox Code Playgroud)
所述<>;
重定向操作器是专用于ksh93的和是相同的标准<>
,除了ksh的截断命令之后的文件已经终止操作。
sed '/./!d'
是一种复杂的编写方式grep .
,但不幸的是,如果其标准输出指向与其标准输入相同的文件,GNU grep 至少会抱怨。你会说一个人可以写:
grep . file | cat 1<>; file
Run Code Online (Sandbox Code Playgroud)
但不幸的是,ksh93(至少我的版本(93u+))中有一个错误,在这种情况下,文件似乎被截断为零长度。
grep . file | { cat; } 1<>; file
Run Code Online (Sandbox Code Playgroud)
似乎可以解决该错误,但现在,它比 sed 命令复杂得多。
这是Perl
它的单行:
perl -pi -e 's/^\s*\n//' yourfile
Run Code Online (Sandbox Code Playgroud)
编辑:根据下面 ruakh 的评论改进了代码。
根据对您的问题的评论中的澄清,例如:
awk -v RS= -v ORS= 1
Run Code Online (Sandbox Code Playgroud)
可以做你想做的。
空记录分隔符是一种特殊情况,它告诉awk
记录是段落(由空行序列分隔)。将输出记录分隔符设置为空字符串也意味着这些段落的内容(没有分隔符)将被连接起来。1
只是打印每条记录的真实条件。
但是,这将省略尾随换行符,因此您可以执行以下操作:
awk -v RS= -v ORS= '1;END{if (NR) printf "\n"}'
Run Code Online (Sandbox Code Playgroud)
我知道如果我提供该文件,事情会更容易,但不幸的是它包含我无法分享的机密信息。与此同时,我写了一个 ruby 脚本,似乎可以解决问题:
require 'csv'
c = CSV.open("outfile1.csv", "w")
CSV.foreach("data.csv", :encoding => 'windows-1251:utf-8') do |row|
row = row.map { |a| a.class == String ? a.gsub(/\r/, '') : a}
c << row
end
c.close
Run Code Online (Sandbox Code Playgroud)
感谢大家的帮助!