我想知道目录中的哪些文件是dos文本文件(而不是unix文本文件)。
我尝试了什么:
find . -name "*.php" | xargs grep ^M -l
它没有给我可靠的结果......所以我正在寻找更好的选择。
有任何建议,想法吗?
由于
澄清
除了我上面所说的,问题是我有一堆没有^ M字符的dos文件(因此我的可靠性说明)。
我目前确定某个文件是否为dos的方式是通过Vim进行的,其底部是:
"filename.php" [dos] [noeol]
答案 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
仅将每个文件名保留一次。