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

Tim*_*ell 115 linux bash grep newline

我想在Linux上用grep搜索包含dos行结尾的文件.像这样的东西:

grep -IUr --color '\r\n' .
Run Code Online (Sandbox Code Playgroud)

以上似乎与文字rn相匹配,这不是所期望的.

这个输出将通过xargs传输到todos,将crlf转换为lf,就像这样

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
Run Code Online (Sandbox Code Playgroud)

Tho*_*mee 146

grep可能不是你想要的工具.它将为每个文件中的每个匹配行打印一行.除非你想在10行文件上运行待机10次,否则grep并不是最好的方法.使用find在树中的每个文件上运行文件,然后通过"CRLF"的那个文件,将为每个具有dos样式行结尾的文件获取一行输出:

find . -not -type d -exec file "{}" ";" | grep CRLF
Run Code Online (Sandbox Code Playgroud)

会得到你这样的东西:

./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
Run Code Online (Sandbox Code Playgroud)

  • 我最喜欢这个答案.我只是"找到了.-type f | xargs文件| grep CRLF`` (7认同)
  • 不是一个好的解决方案,依赖于`file`程序的那种(无证件,面向人类消费)行为.这非常脆弱.对于(仅一个)示例:它不适用于XML文件,`file`报告`XML文档文本`,无论换行类型如何. (6认同)
  • grep的-l选项告诉它只列出文件(一次)而不是列出每个文件中的匹配项. (5认同)
  • @leonbloy,在我的“find (GNU findutils) 4.4.2”(Ubuntu 12.04)上,该选项似乎是小写的“-m /dev/null”。 (2认同)

pjz*_*pjz 112

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

grep -IUr --color "^M"
Run Code Online (Sandbox Code Playgroud)

将起作用 - 如果^M您按照我的建议输入了文字CR.

如果需要文件列表,还要添加该-l选项.

说明

  • -I 忽略二进制文件
  • -U阻止grep去除CR字符.默认情况下,如果它确定它是文本文件,它会这样做.
  • -r 以递归方式读取每个目录下的所有文件.

  • @akostadinov +1,但反引词被解释出你的评论;)换句话说,第二个选项是**grep $(printf'\ r')`**.但对于涉及bash的大多数实际用途,我会坚持使用`$'\ r'`. (4认同)
  • 作为一个快速的黑客,但我认为人类的readbale解决方案将是:grep $'\ r'/ bash shell only /或grep`printf'\ r'` (3认同)
  • 注意:选项`-U`仅与Windows(或cygwin)相关,但它在那里至关重要.在Windows上,没有它,该命令将无法运行. (3认同)
  • 选项`-I`有什么意义?通过手册,在我看来,二进制文件被认为是不匹配的.不应该将`-I`和`-U`(强制执行二进制类型)的组合导致所有文件被视为不匹配? (3认同)
  • 您提到了“ -l”标志作为附加选项,但是我认为应该将其包含在主要答案中,因为该问题实质上要求提供文件列表。此外,它还可以加快搜索速度。 (2认同)

小智 51

grep -IUlr $'\r'
Run Code Online (Sandbox Code Playgroud)

explainhell.com - grep -IUlr

  • 谢谢!为了清楚地了解那些追随者,bash手册说"形式$'字符串'的字是专门处理的.单词扩展为字符串,反斜杠转义字符被ANSI C标准指定替换." (另见[支持的代码列表](http://www.gnu.org/software/bash/manual/bashref.html#ANSI_002dC-Quoting)) (9认同)
  • 那个特定于bash的是什么?应该注意的是它. (4认同)
  • 这似乎没有给出正确的答案,它给了我所有文件 (3认同)

Lin*_*lin 16

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

grep -lUP '\r$'
Run Code Online (Sandbox Code Playgroud)

可用于.


小智 7

# 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
Run Code Online (Sandbox Code Playgroud)


des*_*ert 6

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

\n
dos2unix -ic /path/to/file\n
Run Code Online (Sandbox Code Playgroud)\n

要递归地执行此操作,您可以使用bash\xe2\x80\x99sglobstar选项,该选项对于当前 shell 启用shopt -s globstar

\n
dos2unix -ic **      # all files recursively\ndos2unix -ic **/file # files called \xe2\x80\x9cfile\xe2\x80\x9d recursively\n
Run Code Online (Sandbox Code Playgroud)\n

或者,您可以使用find以下方法:

\n
find -type f -exec dos2unix -ic {} +            # all files recursively (ignoring directories)\nfind -name file -exec dos2unix -ic {} + # files called \xe2\x80\x9cfile\xe2\x80\x9d recursively\n
Run Code Online (Sandbox Code Playgroud)\n