12

我有数百 GB 的数据需要使用 Cygwin 中的 unix paste 实用程序粘贴在一起,但如果文件中有 Windows EOL 字符,它将无法正常工作。数据可能有也可能没有 Windows EOL 字符,如果不需要的话,我不想花时间运行 dos2unix。

所以我的问题是,在 Cygwin 中,我怎样才能确定这些文件是否具有 Windows EOL CRLF 字符?

我尝试创建一些测试数据并运行

sed -r 's/\r\n//' testdata.txt

但无论是否运行了 dos2unix,这似乎都匹配。

谢谢。

4

8 回答 8

21

file(1)实用程序知道其中的区别:

$ file * | grep ASCII
2:                                       ASCII text
3:                                       ASCII English text
a:                                       ASCII C program text
blah:                                    ASCII Java program text
foo.js:                                  ASCII C++ program text
openssh_5.5p1-4ubuntu5.dsc:              ASCII text, with very long lines
windows:                                 ASCII text, with CRLF line terminators

file(1)已针对尝试读取尽可能少的文件进行了优化,因此您可能很幸运,并且在查找和修复 CRLF 终止符时大大减少了需要执行的磁盘 IO 量。

请注意,CRLF 的某些情况应该保留:SMTP的捕获将使用 CRLF。但这取决于你。:)

于 2011-03-17T23:42:47.057 回答
4
#!/bin/bash
for i in $(find . -type f); do
        if file $i | grep CRLF ; then
                echo $i
                file $i
                #dos2unix "$i"
        fi
done

当您准备好转换它们时,取消注释 "#dos2unix "$i""。

于 2011-11-17T10:33:06.300 回答
3

您可以使用以下方法查找file

file /mnt/c/BOOT.INI 
/mnt/c/BOOT.INI: ASCII text, with CRLF line terminators

CRLF 是这里的重要值。

于 2011-03-17T23:44:23.380 回答
2

如果您希望退出代码与 不同sed,则不会。它将根据比赛执行替换或不替换。除非出现错误,否则退出代码将为真。

但是,您可以从 获取可用的退出代码grep

#!/bin/bash
for f in *
do
    if head -n 10 "$f" | grep -qs $'\r'
    then
        dos2unix "$f"
    fi
done
于 2011-03-18T01:50:50.583 回答
2

grep 递归,带有文件模式过滤器

grep -Pnr --include=*file.sh '\r$' .

输出文件名、行号和行本身

./test/file.sh:2:here is windows line break
于 2015-10-22T13:04:44.873 回答
1

如上所述,“文件”解决方案有效。也许下面的代码片段可能会有所帮助。

#!/bin/ksh
EOL_UNKNOWN="Unknown"       # Unknown EOL
EOL_MAC="Mac"               # File EOL Classic Apple Mac  (CR)
EOL_UNIX="Unix"             # File EOL UNIX               (LF)
EOL_WINDOWS="Windows"       # File EOL Windows            (CRLF)
SVN_PROPFILE="name-of-file" # Filename to check.
...

# Finds the EOL used in the requested File
# $1 Name of the file (requested filename)
# $r EOL_FILE set to enumerated EOL-values.
getEolFile() {
    EOL_FILE=$EOL_UNKNOWN

    # Check for EOL-windows
    EOL_CHECK=`file $1 | grep "ASCII text, with CRLF line terminators"`
    if [[ -n $EOL_CHECK ]] ; then
       EOL_FILE=$EOL_WINDOWS
       return
    fi

    # Check for Classic Mac EOL
    EOL_CHECK=`file $1 | grep "ASCII text, with CR line terminators"`
    if [[ -n $EOL_CHECK ]] ; then
       EOL_FILE=$EOL_MAC
       return
    fi

    # Check for Classic Mac EOL
    EOL_CHECK=`file $1 | grep "ASCII text"`
    if [[ -n $EOL_CHECK ]] ; then
       EOL_FILE=$EOL_UNIX
       return
    fi

    return
   } # getFileEOL   
   ...

   # Using this snippet
   getEolFile $SVN_PROPFILE
   echo "Found EOL: $EOL_FILE"
   exit -1
于 2012-01-22T08:43:38.360 回答
1

感谢使用 file(1) 命令的提示,但是它确实需要更多的改进。我遇到的情况不仅是纯文本文件,而且一些“.sh”脚本都有错误的 eol。并且“文件”将它们报告如下,无论 eol 是什么:

xxx/y/z.sh: application/x-shellscript

所以需要“file -e soft”选项(至少对于 Linux):

bash$ find xxx -exec file -e soft {} \; | grep CRLF

这将在目录 xxx 和 subdirs 中找到所有带有 DOS eol 的文件。

于 2012-05-29T11:20:36.370 回答
1

您可以使用 dos2unix 的 -i 选项来获取有关 DOS Unix Mac 换行符(按此顺序)、BOM 和文本/二进制文件的信息,而无需转换文件。

$ dos2unix -i *.txt
    6       0       0  no_bom    text    dos.txt
    0       6       0  no_bom    text    unix.txt
    0       0       6  no_bom    text    mac.txt
    6       6       6  no_bom    text    mixed.txt
   50       0       0  UTF-16LE  text    utf16le.txt
    0      50       0  no_bom    text    utf8unix.txt
   50       0       0  UTF-8     text    utf8dos.txt

使用“c”标志,dos2unix 将报告将被转换的文件,iow 文件有 DOS 换行符。要报告带有 DOS 换行符的所有 txt 文件,您可以这样做:

$ dos2unix -ic *.txt
dos.txt
mixed.txt
utf16le.txt
utf8dos.txt

要仅转换这些文件,您只需执行以下操作:

dos2unix -ic *.txt | xargs dos2unix

如果您需要对目录进行递归,请执行以下操作:

find -name '*.txt' | xargs dos2unix -ic | xargs dos2unix

另请参见 dos2unix 的手册页。

于 2015-10-23T07:06:42.927 回答