如何在 Linux 上使用 grep 搜索包含 DOS 行尾 (CRLF) 的文件?

Posted

技术标签:

【中文标题】如何在 Linux 上使用 grep 搜索包含 DOS 行尾 (CRLF) 的文件?【英文标题】:How do you search for files containing DOS line endings (CRLF) with grep on Linux? 【发布时间】:2010-09-09 14:02:36 【问题描述】:

我想在 Linux 上使用 grep 搜索包含 DOS 行结尾的文件。像这样的:

grep -IUr --color '\r\n' .

以上内容似乎与文字 rn 匹配,这不是我们想要的。

this 的输出将通过 xargs 传递到 todos 中,像这样将 crlf 转换为 lf

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'

【问题讨论】:

你试过dos2unix吗?它会自动修复行尾。 我不太确定,但 iirc 在 ' 和 " 中引用模式是有区别的。在 ' 中包含的模式中的 Afaik 转义序列被解释为正确的字符串,因此 '\r' 将是等效的到 "\\r" 和 "\r" 与 '. 没有等价物(至少在该符号中) Anticom:在这种情况下,您是正确的,' 和 " 之间的区别无关紧要;但是,通常它们是不同的,因为 ' 包围的字符串是弱引用的,而 " 是强引用的。我利用的最大优势是 $ 扩展或 `` 不要在弱引用字符串中扩展。请参阅bash-hackers on quoting 了解更多信息。 最简单的方法是使用现代dos2unix-ic 开关。对于 LF 文件,您可以使用 unix2dos-ic 进行搜索。它不会修改文件。仅报告。 因为这是有关 Linux 上 Windows 行尾/回车的任何问题的最佳答案,我认为值得注意的是,您可以在终端中使用命令查看它们cat -v somefile.txt;他们显示为^M 【参考方案1】:

使用 Ctrl+VCtrl+M 在 grep 字符串中输入文字回车符.所以:

grep -IUr --color "^M"

会起作用 - 如果 ^M 有一个文字 CR,你按照我的建议输入。

如果您想要文件列表,还需要添加-l 选项。

说明

-I忽略二进制文件 -U 防止 grep 删除 CR 字符。默认情况下,如果它确定它是一个文本文件,它就会这样做。 -r递归读取每个目录下的所有文件。

【讨论】:

作为一种可行的快速破解方法,但我认为人类 readbale 解决方案将是:grep $'\r' /bash shell only/ 或 grep printf '\r' @akostadinov +1,但是反引号被您的评论解释了;)换句话说,第二个选项是 grep $(printf '\r')。但对于涉及 bash 的大多数实际用途,我会坚持使用 $'\r' 注意:-U 选项仅与 Windows(或 cygwin)相关,但在那里很关键。在 Windows 上,如果没有它,该命令将无法运行。 -I 选项的意义何在?根据手册,在我看来二进制文件被认为是不匹配的。 -I-U(强制二进制类型)的组合不应该导致所有文件都被视为不匹配吗? 您提到 '-l' 标志作为附加选项,但我认为它应该包含在主要答案中,因为该问题本质上要求提供文件列表。此外,它还可以加快搜索速度。【参考方案2】:

grep 可能不是您想要的工具。它将为每个文件中的每个匹配行打印一行。除非你想在一个 10 行的文件上运行 10 次 todos,否则 grep 并不是最好的方法。使用 find 在树中的每个文件上运行文件,然后对“CRLF”进行 grepping,将为每个具有 dos 样式行结尾的文件提供一行输出:

find . -not -type d -exec file "" ";" | grep CRLF

会给你类似的东西:

./1/dos1.txt: ASCII text, with CRLF line terminators
./2/dos2.txt: ASCII text, with CRLF line terminators
./dos.txt: ASCII text, with CRLF line terminators

【讨论】:

我已经破解了这个,但还是谢谢你。 grep -IUrl --color '^M' . | xargs -ifile fromdos 'file' grep 的 -l 选项告诉它只列出文件(一次)而不是列出每个文件中的匹配项。 不是一个好的解决方案,依赖于file 程序的(未记录的,面向人类消费的)行为。这是非常脆弱的。对于(仅一个)示例:它不适用于 XML 文件,file 报告 XML document text 无论换行符类型如何。 @leonbloy,我的find (GNU findutils) 4.4.2(Ubuntu 12.04)上的选项似乎是小写的-m /dev/null 我最喜欢这个答案。我只是做了find . -type f | xargs file | grep CRLF【参考方案3】:

如果你的 grep 版本支持 -P (--perl-regexp) 选项,那么

grep -lUP '\r$'

可以使用。

【讨论】:

这很慢...【参考方案4】:
# list files containing dos line endings (CRLF)

cr="$(printf "\r")"    # alternative to ctrl-V ctrl-M

grep -Ilsr "$cr$" . 

grep -Ilsr $'\r$' .   # yet another & even shorter alternative

【讨论】:

【参考方案5】:

查询是搜索...我有类似的问题...有人提交了混合行 结束到版本控制,所以现在我们有一堆文件0x0d 0x0d 0x0a 行尾。请注意

grep -P '\x0d\x0a'

找到所有行,而

grep -P '\x0d\x0d\x0a'

grep -P '\x0d\x0d'

没有发现任何行,因此 grep 中可能存在“其他”内容 说到行尾模式……对我来说很不幸!

【讨论】:

【参考方案6】:

如果像我一样,您的极简主义 unix 不包含 file 命令之类的细节,并且您的 grep 表达式中的反斜杠不配合,试试这个:

$ for file in `find . -type f` ; do
> dump $file | cut -c9-50 | egrep -m1 -q ' 0d| 0d'
> if [ $? -eq 0 ] ; then echo $file ; fi
> done

您可能希望对上述内容进行的修改包括:

调整 find 命令以仅定位您要扫描的文件 将 dump 命令更改为 od 或您拥有的任何文件转储实用程序 确认 cut 命令包括前导空格和尾随空格,以及 dump 实用程序输出的十六进制字符 将 dump 输出限制为前 1000 个字符左右以提高效率

例如,使用 od 而不是 dump 可能适合您:

 od -t x2 -N 1000 $file | cut -c8- | egrep -m1 -q ' 0d| 0d|0d$'

【讨论】:

【参考方案7】:

使用 RipGrep(取决于您的 shell,您可能需要引用最后一个参数):

rg -l \r
-l, --files-with-matches
Only print the paths with at least one match.

https://github.com/BurntSushi/ripgrep

【讨论】:

这似乎没有给出正确的答案,它给了我所有的文件【参考方案8】:

你可以在 unix 中使用 file 命令。它为您提供文件的字符编码以及行终止符。

$ file myfile
myfile: ISO-8859 text, with CRLF line terminators
$ file myfile | grep -ow CRLF
CRLF  

【讨论】:

【参考方案9】:

dos2unix 有一个文件信息选项,可用于显示要转换的文件:

dos2unix -ic /path/to/file

要递归地执行此操作,您可以使用bashglobstar 选项,对于当前的shell,该选项是通过shopt -s globstar 启用的:

dos2unix -ic **      # all files recursively
dos2unix -ic **/file # files called “file” recursively

您也可以使用find

find -type f -exec dos2unix -ic  +            # all files recursively (ignoring directories)
find -name file -exec dos2unix -ic  + # files called “file” recursively

【讨论】:

以上是关于如何在 Linux 上使用 grep 搜索包含 DOS 行尾 (CRLF) 的文件?的主要内容,如果未能解决你的问题,请参考以下文章

linux 上查找包含特定文本的所有文件

linux grep sed awk

查找linux系统上指定文件中字符串的所在行及其上下几行的内容

4-4 linux的grep搜索命令

Linux grep命令

Linux grep命令