如何在git bash中检测dos格式文件

如何在git bash中检测dos格式文件

Git Bash 是 Windows 中安装 Git 时获得的一个不错的 bash shell。它内部捆绑了其他典型的 UNIX 工具,例如 grep、sed、awk、perl。它没有文件命令。

在此 shell 中,我想检测具有 DOS 样式行结尾的文件。我以为这个命令会起作用,但事实并非如此:

grep -l ^M$ *

即使文件没有 CR 行结尾匹配,它也不起作用。例如,如果我创建 2 个示例文件hello.unixhello.dos,我可以确认wc具有hello.unix6 个字符,并且hello.dos由于额外的 CR 而具有 7 个字符,但这两个文件都与grep.那是:

$ cat hello.*
hello
hello

$ wc hello.*
      1       1       7 hello.dos
      1       1       6 hello.unix
      2       2      13 total

$ grep -l ^M hello.*
hello.dos
hello.unix

grep这是Git Bash实现中的错误吗?还有另一种方法可以查找所有具有 DOS 风格行结尾的文件吗?

答案1

编辑:愚蠢的我。当然^M就是CR;并且您的命令应该有效(在我的系统上有效)。但是,您需要键入 Ctrl-V Ctrl-M 才能获取文字 '\r'/CR (而不是两个字符^M)。

备择方案:

做这个:

find dir -type f -print0 | xargs -0 grep -l `printf '\r\n'`

或这个:

find dir -type f -print0 | xargs -0 grep -lP '\r\n'

您还可以使用文件实用程序(不确定它是否随 GIT bash 一起提供):

find dir -type f -print0 | xargs -0 file | grep CRLF

答案2

我不知道 git bash,但也许

if [ "$(tr -cd '\r' < file | wc -c)" -gt 0 ]; then
  echo there are CR characters in there
fi

会工作。想法是不使用文本可以特殊处理 CR 和 LF 字符的实用程序。

如果这不起作用,那么也许

if od -An -tx1 < file | grep -q 0d; then
  echo there are CR characters in there
fi

挂钩查找:

find . -type f -exec sh -c 'od -An -tx1 < "$1" | grep -q 0d' sh {} \; -print

答案3

@sch 引导我找到了这个解决方案:

sed -bne '/\r$/ {p;q}' < /path/to/file | grep -q .

如果文件中有任何以 CR 结尾的行,则以 TRUE 退出。要将其挂钩到 find 中:

find /path/to/ -type f -exec sh -c 'sed -bne "/\r$/ {p;q}" < "$1" | grep -q .' sh {} \; -print

我想我知道为什么grep -l ^M hello.*在这个 shell 中不起作用:似乎在 Git Bash 中^M字符被从所有命令行参数中删除,因此grep永远不会真正接收到该字符,因此所有文件都匹配。这种行为不仅出现在命令行中,而且出现在 shell 脚本中。

所以关键是^M用其他符号来表达这个字符,比如\r,而不是字面意思。

答案4

在 Linux/Ubuntu 上使用 file 命令。如果文件是 DOS 格式,输出将包含“with CRLF line terminators”字样。如果文件是 UNIX 格式,则输出中不会出现此类单词。在下面的示例中,del.txt 为 DOS 格式,del 为 UNIX 格式。

$ file del.txt
del.txt: C source, ASCII text, with CRLF line terminators
$ echo "hello" > del
user@decatur2:~/manpuriav$ file del
del: ASCII text

相关内容