grep查找包含^ M的文件(Windows回车)


70

我使用Linux。在成千上万的配置文件中隐藏着一个讨厌的^ M(Windows返回Windows),我必须找到它,因为它会使服务器发生故障。

如何在充满配置文件的目录层次结构中找到^ M?

我想我无法在bash命令行上输入^ M。但是我有一个名为m.txt的文本文件



窗户将是^ M ^ J
barlop

2
“我无法在bash命令行上输入^ M”。是的你可以。尝试使用control-V Control-M
Hennes

Answers:


89
grep -r $'\r' *

使用-r递归搜索和$''在猛砸C风格的逃逸。

更多,如果您确定它是文本文件,则应该可以安全运行

tr -d $'\r' < filename

删除\r文件中的所有内容。

如果使用GNU sed,则-i可以执行就地编辑,因此您无需回写:

sed $'s/\r//' -i filename

10
@Nicolas:您可以通过按^ V ^ M在命令行中输入^ M,但最好使用$'\r'
丹尼斯·威廉姆森

太好了!也感谢^ V ^ M技巧:-)
Nicolas Raoul

5
在Cygwin下,需要-U才能完成此工作。和-n会告诉你的行号:grep的-r -U -n -e $ '\ r'
赖BLOME

4
在grep命令中添加-l以仅查看文件名。否则,您可能会受到匹配线的轰炸。
布伦丹·伯德

1
@uprego不知道您现在是否了解它们,但是fyi和其他人搜索$'了manpage的第一篇文章bash(1),基本上,您可以看到它就像在编写C文字字符串一样。至于command < filename使用<>称为重定向,这是我第一次看到有人称其为更大的表达REDIRECTION在中搜寻bash(1)
livibetter

12

当我尝试时,我可以断定它是可以正常工作的,但是这些行却打印空白。添加选项:

--color=never

如果遇到此问题,我认为这是转义字符,用于突出显示颜色干扰\r字符。


2

如果您的服务器没有bash shell,则另一种方法是将-fon选项grep与包含的准备好的文件结合使用\r

要创建文件:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

实际进行搜索

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

或者您可以有点懒,只需输入*,

$ grep -f /tmp/cr *

该选项在用于指定包含模式来匹配,每行一个文件。在这种情况下,只有一种模式。-f filenamegrep


1

要在行尾字符上使用grep,我想您必须告诉grep该文件是二进制文件。

-l(字母L)仅用于打印文件名

-P用于perl正则表达式(因此\ x0d转换为\ r或^ M)

grep -l --binary -P '\x0d' *

1

如果我正确理解了您的问题,那么您真正想要的是将所有行尾标准化为Unix LF(\x0a)标准。这与仅盲目删除CR(\xod)不同。

如果碰巧有一些Mac文件,其中仅将CR用于换行符,则将销毁这些文件。(是的,Mac应该使用LF已有近20年的历史,但是(在2019年)仍然有许多Mac应用仅使用CR)。

您可以使用Perl的\R 换行符转义来替换任何形式的换行符\n

perl -i.bak -pe 's/\R/\n/g' $your_file

这将替换in中的任何换行符,并\n$your_file中保留原始文件的备份${your_file}.bak


0

如果您在Mac上并且使用自制软件,则可以执行以下操作:

brew install tofrodos
fromdos file.txt

file.txt中删除所有Windows回车符

要切换回Windows回车,

todos file.txt

要搜索文件夹并清除来自dos的所有文件,请运行以下命令:find。类型的f-名称“ * .java” | xargs fromdos
Taiko

0

在正则表达式样式中,各种换行符:

Windows(CR LF)
\r\n

Unix(LF)
\n

由于\r\n序列是相当独特的,我认为您应该能够以这种方式进行搜索?

更糟糕的是,Mac以前只用'\ r'代替换行符。我无法验证这一点,但我认为MacOSX世代不再这样做了。

较旧的Mac(CR)
\r


在包含m.txt的目录中,grep "\r\n" *没有任何结果。既没有结果,egrep -e "\r\n" *也没有结果grep -E "\r\n" *
Nicolas Raoul

@nicolas啊,我误会了..你的意思是CR只是\r我的坏。完整的Windows换行符确实是\r\nCRLF
Jeff Atwood

0

遵循先前的答案,“ tr”方法很好:

533 $如果[[--n“ tr -cd "\r" <~/.bashrc”]]; 然后回显“ DOS”;否则回显“ UNIX”;科幻

UNIX系统

534 $如果[[--n“ tr -cd "\r" <dosfile.txt”]]; 然后回显“ DOS”;否则回显“ UNIX”;科幻

DOS

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.