Как найти символ конца окна (EOL)
У меня есть несколько сотен ГБ данных, которые мне нужно вставить вместе с помощью утилиты unix paste в Cygwin, но она не будет работать должным образом, если в файлах есть буквы EOL. Данные могут иметь или не иметь оконных символов EOL, и я не хочу тратить время на выполнение dos2unix, если мне это не нужно.
Итак, мой вопрос в Cygwin, как я могу выяснить, имеют ли эти файлы символы EOL CRLF Windows?
Я попытался создать некоторые тестовые данные и запустить
sed -r 's/\r\n//' testdata.txt
Но это похоже на совпадение независимо от того, был ли dos2unix запущен или нет.
Спасибо.
Ответы
Ответ 1
Утилита 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. Но это вам.:)
Ответ 2
Вы можете узнать, используя file
:
file /mnt/c/BOOT.INI
/mnt/c/BOOT.INI: ASCII text, with CRLF line terminators
CRLF является значимым значением здесь.
Ответ 3
Если вы ожидаете, что код выхода будет отличаться от sed
, этого не будет. Он будет выполнять замену или нет в зависимости от соответствия. Код выхода будет истинным, если не будет ошибки.
Однако вы можете получить полезный код выхода из grep
.
#!/bin/bash
for f in *
do
if head -n 10 "$f" | grep -qs $'\r'
then
dos2unix "$f"
fi
done
Ответ 4
#!/bin/bash
for i in $(find . -type f); do
if file $i | grep CRLF ; then
echo $i
file $i
#dos2unix "$i"
fi
done
Uncomment "# dos2unix" $i "", когда вы будете готовы их преобразовать.
Ответ 5
Спасибо за подсказку, чтобы использовать команду 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 и subdirs.
Ответ 6
Как указано выше, работает "файл". Возможно, следующий фрагмент кода может помочь.
#!/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
Ответ 7
grep рекурсивный, с фильтром шаблонов файлов
grep -Pnr --include=*file.sh '\r$' .
имя выходного файла, номер строки и сама строка
./test/file.sh:2:here is windows line break
Ответ 8
Вы можете использовать параметр dos2unix -i для получения информации о разрывах строк в 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.