Как найти символ конца строки (EOL) в Windows - PullRequest
11 голосов
/ 18 марта 2011

У меня есть несколько сотен ГБ данных, которые мне нужно вставить вместе с помощью утилиты unix paste в Cygwin, но она не будет работать должным образом, если в файлах есть символы Windows EOL.Данные могут содержать или не содержать символы Windows EOL, и я не хочу тратить время на запуск dos2unix, если мне это не нужно.

Итак, мой вопрос в Cygwin, как я могу выяснить, имеют ли эти файлы символы Windows EOL CRLF?

Я пытался создать некоторые тестовые данные и запустить

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

Но это похоже на совпадение независимо от того, был ли запущен dos2unix.

Спасибо.

Ответы [ 8 ]

18 голосов
/ 18 марта 2011

Утилита 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.

Обратите внимание, что некоторые случаи CRLF должны оставаться на месте: при захвате SMTP будет использоваться CRLF. Но это зависит от вас. :)

3 голосов
/ 18 марта 2011

Вы можете узнать, используя file:

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

CRLF является значимым значением здесь.

2 голосов
/ 17 ноября 2011
#!/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 "", когда вы будете готовы конвертировать их.

2 голосов
/ 18 марта 2011

Если вы ожидаете, что код выхода будет отличаться от sed, это не будет. Он будет выполнять замену или нет в зависимости от матча. Код выхода будет истинным, если не будет ошибки.

Вы можете получить код выхода из grep, однако.

#!/bin/bash
for f in *
do
    if head -n 10 "$f" | grep -qs $'\r'
    then
        dos2unix "$f"
    fi
done
1 голос
/ 22 октября 2015

grep recursive, с фильтром шаблонов файлов

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

имя выходного файла, номер строки и сама строка

./test/file.sh:2:here is windows line break
1 голос
/ 29 мая 2012

Спасибо за подсказку по использованию команды 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

Находит все файлы с DOS eol в каталоге xxx и его подкаталогах.

0 голосов
/ 23 октября 2015

Вы можете использовать опцию -i dos2unix для получения информации о переносах строк в DOS Unix Mac (в указанном порядке), спецификациях и текстовых / двоичных файлах без преобразования файла.

$ 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. Чтобы сообщить обо всех TXT-файлах с переносами строк DOS, вы можете сделать это:

$ 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.

0 голосов
/ 22 января 2012

Как указано выше, решение 'file' работает.Может быть, поможет следующий фрагмент кода.

#!/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
...