如何在linux文件系统中找到dos格式文件

时间:2011-01-18 01:41:00

标签: linux shell vim find

我想知道目录中的哪些文件是dos文本文件(而不是unix文本文件)。

我尝试了什么:

find . -name "*.php" | xargs grep ^M -l

它没有给我可靠的结果......所以我正在寻找更好的选择。

有任何建议,想法吗?

由于

澄清

除了我上面所说的,问题是我有一堆没有^ M字符的dos文件(因此我的可靠性说明)。

我目前确定某个文件是否为dos的方式是通过Vim进行的,其底部是:

"filename.php" [dos] [noeol]

8 个答案:

答案 0 :(得分:14)

怎么样:

find . -name "*.php" | xargs file | grep "CRLF"

我认为尝试使用^M尝试查找文件并不可靠。

答案 1 :(得分:9)

不确定你的意思是“不可靠”,但你可能想尝试:

find . -name '*.php' -print0 | xargs -0 grep -l '^M$'

这会使用更多 atrocious-filenames-with-spaces-in-friendly-friendly 选项,并且只会在行尾之前找到回车符。

请记住,^M是一个 CTRL M 字符,而不是两个字符。

而且它会列出甚至一个行处于DOS模式的文件,这可能是你想要的,因为那些将是由非UNIX编辑器破坏的UNIX文件。 / p>


根据您的更新,vim将您的文件报告为DOS格式:

如果vim 将其报告为DOS格式,则每个行都以CRLF结尾。这就是vim的工作方式。如果即使一个行没有CR,那么它也被视为UNIX格式,并且^M字符在缓冲区中可见。如果它是所有DOS格式,则不显示^M个字符:

  

Vim会查找dos和unix行结尾,但Vim内置了unix格式的首选项。
  
   - 如果文件中的所有行都以CRLF结尾,则将应用dos文件格式,这意味着在将行读入缓冲区时删除每个CRLF,缓冲区'ff'选项将为dos。    - 如果一行或多行仅以LF结尾,则将应用unix文件格式,这意味着每个LF都被删除(但每个CR将出现在缓冲区中,并将显示为^ M),缓冲区'ff'选项将是unix。

如果确实想知道文件中的内容,请不要依赖像vim这样太智能的工具: - )

使用:

od -xcb input_file_name | less

并自行检查行结尾。

答案 2 :(得分:1)

这很像你原来的解决方案;因此,你可能更容易记住:

find . -name "*.php" | xargs grep "\r" -l

思维过程:

在VIM中,要删除您输入的^ M:

 %s:/^M//g

其中^是您的Ctrl键,M是ENTER键。但我永远不会记住键入打印该序列的键,因此我总是使用以下方法删除它们:

 %s:/\r//g

所以我的推论是\ r和^ M是等价的,前者更容易记住输入。

答案 3 :(得分:1)

我好运

find . -name "*.php" -exec grep -Pl "\r" {} \;

答案 4 :(得分:0)

GNU find

find . -type f -iname "*.php"  -exec file "{}" + | grep CRLF

我发现那些DOS php文件后你不知道你想做什么,但如果你想将它们转换为unix格式,那么

find . -type f -iname "*.php"  -exec dos2unix "{}" +;

就足够了。没有必要专门检查它们是否是DOS文件。

答案 5 :(得分:0)

如果您希望vim告诉您哪种文件采用此格式,您可以使用以下脚本:

"use this script to check which files are in dos format according to vim
"use: in the folder that you want to check
"create a file, say res.txt
"> vim -u NONE --noplugins res.txt
"> in vim: source this_script.vim

python << EOF
import os
import vim

cur_buf =  vim.current.buffer

IGNORE_START = ''.split()
IGNORE_END = '.pyc .swp .png ~'.split()

IGNORE_DIRS = '.hg .git dd_ .bzr'.split()

for dirpath, dirnames, fnames in os.walk(os.curdir):
  for dirn in dirnames:
    for diri in IGNORE_DIRS:
      if dirn.endswith(diri):
        dirnames.remove(dirn)
        break
  for fname in fnames:
    skip = False
    for fstart in IGNORE_START:
      if fname.startswith(fstart):
        skip = True
    for fend in IGNORE_END:
      if fname.endswith(fend):
        skip = True
    if skip is True:
      continue
    fname = os.path.join(dirpath, fname)
    vim.command('view {}'.format(fname))
    curr_ff = vim.eval('&ff')
    if vim.current.buffer != cur_buf:
      vim.command('bw!')
    if curr_ff == 'dos':
      cur_buf.append('{} {}'.format(curr_ff, fname))
EOF

你的vim需要用python编译(python用于遍历文件夹中的文件,这可能是一种更简单的方法,但我真的不知道它....

答案 6 :(得分:0)

如果您的dos2unix命令具有-i选项,则可以使用该功能在具有DOS换行符的目录中查找文件。

$ man dos2unix
.
.
.
     -i[FLAGS], --info[=FLAGS] FILE ...
           Display file information. No conversion is done.

    The following information is printed, in this order:
    number of DOS line breaks,
    number of Unix line breaks,
    number of Mac line breaks,
    byte order mark,
    text or binary, file name.
.
.
.
Optionally extra flags can be set to change the (-i) output.
.
.
.
           c   Print only the files that would be converted.

以下单行脚本为:

  • find此目录树中的所有文件,
  • 对所有文件运行dos2unix,以确定要更改的文件,
  • 对要更改的文件运行dos2unix

$ find . -type f | xargs -d '\n' dos2unix -ic | xargs -d '\n' dos2unix

答案 7 :(得分:0)

我一直在使用cat -e来查看行尾文件的内容。

^M用作单个 CTRL M 字符对我来说并不是很有效(就像我只按 return < / kbd>,而没有实际插入不可打印的^M行尾-已通过echo ' CTRL M ' | cat -e测试)我最终要做的事情可能看起来太多了,但是仍然可以完成工作:

grep '$' *.php | cat -e | grep '\^M\$' | sed 's/:.*//' | uniq

,其中

  • 第一个grep只是在每个文件的每一行之前添加文件名(可以替换为awk '{print FILENAME, $0}',但是grep在我的文件集上工作得更快) cat -e显式打印不可打印的行尾;
  • 第二个grep查找以^M$结尾的行,而^M 是两个字符;
  • sed部分仅保留文件名(可用cut -d ':' -f 1替换);
  • uniq仅将每个文件名保留一次。