在字段中间(不是行尾)放置一些带有未正确放置的换行符的分隔文件,在Vim中显示为^ M.它们源自freebcp(在Centos 6上)导出的MSSQL数据库。以十六进制方式转储数据显示\ r \ n模式:
$ xxd test.txt | grep 0d0a
0000190: 3932 3139 322d 3239 3836 0d0a 0d0a 7c43
我可以用awk删除它们,但我无法用sed做同样的事情。
这在awk中工作,完全删除换行符:
awk 'gsub(/\r/,""){printf $0;next}{print}'
但这在sed中没有,留下换行符:
sed -i 's/\r//g'
这似乎没有效果:
sed -i 's/\r\n//g'
在sed表达式中使用^ M(ctrl + v,ctrl + m)似乎也不起作用。
对于这类任务,sed更容易理解,但我正在努力学习更多两者。我使用sed是不正确的,还是有限制?
答案 0 :(得分:39)
您可以使用命令行工具dos2unix
dos2unix input
或使用tr
命令:
tr -d '\r' <input >output
实际上,您可以在vim
:
:e ++ff=dos
:w ++ff=unix
:e!
方法B:
:e ++ff=dos
:set ff=unix
:w
如果要删除文件中的\r\n
序列,请在vim
中尝试以下命令:
:e ++ff=unix " <-- make sure open with UNIX format
:%s/\r\n//g " <-- remove all \r\n
:w " <-- save file
您的awk
解决方案正常。另外两个sed
解决方案:
sed '1h;1!H;$!d;${g;s/\r\n//g}' input
sed ':A;/\r$/{N;bA};s/\r\n//g' input
答案 1 :(得分:20)
我认为sed
的某些版本无法将\r
识别为角色。但是,您可以使用bash
功能来解决此限制:
echo $string | sed $'s/\r//'
在这里,让bash
将'\ _'替换为$'...'
构造中的实际回车符,然后将其作为命令传递给sed
。 (假设您使用bash
;其他shell应该具有类似的构造。)
答案 2 :(得分:6)
另一种方法
awk 1 RS='\r\n' ORS=
\r\n
1
始终为true,如果没有使用操作块{print}
答案 3 :(得分:4)
sed -e 's/\r//g' input_file
这对我有用。 -e 的差异,而不是 -i 命令。
我还提到在不同平台上看到的行为有所不同。
我的是:sed --version
This is not GNU sed version 4.0