我有一个很大的 CSV 文件。其中一个字段包含错误。此错误在文件中显示为新行。
从现在开始,我一直在使用记事本++和此命令来纠正问题:
\r";" =>“;”
我怎样才能用 sed 做同样的事情?
我已经尝试过了
sed -i 's/\r";"/";"/g' /path/file.csv
sed -i 's/^";"/";"/g' /path/file.csv
没有成功,这里有人可能知道正确的命令
答案1
了解 sed 是逐行工作的,这一点很重要。 sed 的作用基本上是:将一行读入其缓冲区没有换行符,在缓冲区上执行命令,打印缓冲区(假设您没有指定标志-n
),将下一行读入其缓冲区等。因此,要使用 sed 合并两行,需要显式强制 sed 处理多个一次单行。要做到这一点,N
、P
和D
命令是您的朋友。
现在,对于您的具体问题,要给您一个具体且经过测试的答案,需要您输入特定类型的输入,但以下是可以执行的操作的一些示例:
这会将每两行合并在一起:
sed $'N;s/[\\n\r]//g'
或者如果您确定始终有 \r\n 行结尾:
sed 'N;s/.\n//'
对于我对你的问题的理解的更定制的方法,虽然不是最好的解决方案,但只要你使用 bash 或其他通过构造支持 C 转义的 shell,这应该可以完成工作$'str'
:
sed $':l;N;/\r\\n";"/{;s/\r\\n";"/";"/g;n;};bl'
或者没有 C 风格的转义结构并带有 \r\n 行结尾(不可协商):
sed ':l;N;/\n";"/{;s/.\n";"/";"/g;n;};bl'
它所做的基本上是将下一行附加到其缓冲区 ( N
) 并测试所需的字符串 ( /\r\\n";"/
)。只要找不到匹配项,脚本就会循环(bl
--> 分支到开头定义的标签)。:l
当找到匹配项时,它会执行花括号之间的 sed 脚本:用 ( ) 替换所有出现的地方\r\\n";"
,";"
并s/\r\\n";"/";"/g
刷新缓冲区并输入下一行 ( n
)。
当然,如果文件很大并且“错误”很少发生,则这可能会运行很长时间并占用大量内存。如果是这种情况,可以使用另一种算法,但我需要一个更好的例子来说明您所面临的问题,以确保我正确理解您的问题。
另外,如果您想更多地了解 sed,我强烈推荐这个网站它可能没有最好的背景颜色,但在我看来是最好的 sed 教程。
答案2
如果您可以接受 Perl 解决方案:
perl -pe 's/\r";"/";"/g' foo.csv >foo_r.csv
答案3
如果你想删除\r
字符,使用命令过滤器会更简单tr
:
cat file.csv | tr -d '\r' >newfile.csv
或直接:
tr -d '\r' <file.csv >newfile.csv
man tr
是你的朋友。警告:tr
旨在用作从其标准输入读取的过滤器,并且它不能像sed -i
.
答案4
我有一个类似的问题需要解决,但我最终使用了 @Fjor 的答案的稍微不同的版本
cat file.csv | tr -d '\n'
(Tr 是 TRanslate,通常是搜索/替换命令,但使用 -d 只会删除所有出现的单引号搜索字符串)
如果我有代表的话,我会把它作为对 Fjor 答案的评论。哦,好吧,无论如何,它就在这里。