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

如何在Linux上使用grep搜索包含DOS行尾(CRLF)的文件?,linux,bash,grep,newline,Linux,Bash,Grep,Newline,我想在Linux上用grep搜索包含DOS行尾的文件。大概是这样的: grep-IUr--color'\r\n'。 上面的内容似乎与literalrn相匹配,这并不是我们想要的 它的输出将通过xargs传输到TODO,从而将crlf转换为lf,如下所示 grep -IUrl --color '^M' . | xargs -ifile fromdos 'file' 使用Ctrl+V、Ctrl+M在grep字符串中输入文本回车字符。因此: grep -IUr --color "^M&q

我想在Linux上用grep搜索包含DOS行尾的文件。大概是这样的:

grep-IUr--color'\r\n'。
上面的内容似乎与literal
rn
相匹配,这并不是我们想要的

它的输出将通过xargs传输到TODO,从而将crlf转换为lf,如下所示

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
使用Ctrl+V、Ctrl+M在grep字符串中输入文本回车字符。因此:

grep -IUr --color "^M"
将起作用-如果
^M
有一个文本CR,您可以按照我的建议输入

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

解释

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

    • grep可能不是您想要的工具。它将为每个文件中的每个匹配行打印一行。除非你想,比方说,在一个10行文件上运行10次TODO,否则grep不是最好的方法。使用“查找”在树中的每个文件上运行文件,然后对“CRLF”进行灰显,将为每个具有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版本支持-p(-perl regexp)选项,那么

      grep -lUP '\r$'
      

      无法使用。

      查询正在搜索。。。我有一个类似的问题。。。有人提交了混合行
      # 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
      
      在版本控制中结束,所以现在我们有一堆
      0x0d
      0x0d
      0x0a
      行尾。注意

      grep -P '\x0d\x0a'
      
      查找所有行,而

      grep -P '\x0d\x0d\x0a'
      

      找不到行,因此grep中可能有“其他”内容
      当涉及到行尾模式时。。。对我来说很不幸

      如果像我一样,您的极简主义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实用程序输出的十六进制字符
      • 将转储限制在前1000个字符左右,以提高效率
      例如,使用od而不是dump时,类似的方法可能适用于您:

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

      rg -l \r
      

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

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

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

      dos2unix-ic/path/to/file
      
      要递归地执行此操作,可以使用
      bash
      globstar
      选项,该选项对于当前shell是通过
      shopt-s globstar
      启用的:

      dos2unix-ic**
      dos2unix-ic**/file#递归称为“file”的文件
      
      或者,您可以使用
      查找

      find-exec dos2unix-ic{}+#递归查找所有文件
      find-name file-exec dos2unix-ic{}+#递归调用“file”的文件
      
      我已经破解了这个,不过还是要谢谢你<代码>grep-IUrl--颜色“^M”xargs-ifile fromdos'file'
      grep的-l选项告诉它只列出文件(一次),而不是列出每个文件中的匹配项。依赖
      文件的行为(未记录,面向人类消费),这不是一个好的解决方案。这是非常脆弱的。例如(仅一个)它不适用于XML文件,
      文件
      报告
      XML文档文本
      ,而不管换行符类型。@leonbloy,在我的
      find(GNU findutils)4.4.2
      (Ubuntu 12.04)上,这个选项似乎是小写的
      -m/dev/null
      。我最喜欢这个答案。我只是找到了-键入f | xargs file | grep CRLF
      作为一种快速破解方法,它会起作用,但我认为HumanReadBale解决方案应该是:grep$'\r'/bash shell only/或grep
      printf'\r'
      @akostadinov+1,但您的注释中会解释反勾号;)换句话说,第二个选项是
      grep$(printf'\r')
      。但是对于涉及bash的大多数实际应用,我会坚持使用
      $'\r'
      。注意:
      -U
      选项只与Windows(或cygwin)相关,但它在那里很关键。在Windows上,如果没有它,命令将无法工作。选项
      -I
      有什么意义?根据手册,在我看来,二进制文件被认为是不匹配的。
      -I
      -U
      (强制使用二进制类型)的组合不应该导致所有文件都被视为不匹配吗?您提到了“-l”标志作为一个附加选项,但我认为它应该包含在主要答案中,因为这个问题本质上需要一个文件列表。而且,它可以加快搜索速度。你试过了吗?它会自动修复行尾。我不太确定,但iirc在“转义序列”中包含的模式中引用“.Afaik”和“.Afaik”是有区别的,因为“转义序列”中包含的模式会被解释为正确的字符串,所以“\r”将等同于“\\r”,而“\r”没有等价物(至少在该符号中)使用“.Anticom”:在这种情况下,你是对的,和之间的区别是不相关的;但是,通常它们是不同的,因为“被包围的字符串是弱引号,而”是强引号。我利用的最大优势是$expansions或“不在弱引号字符串中展开”。有关更多信息,请参阅
      -l, --files-with-matches
      Only print the paths with at least one match.
      
      $ file myfile
      myfile: ISO-8859 text, with CRLF line terminators
      $ file myfile | grep -ow CRLF
      CRLF