Как может я программно (т.е. не использование vi
) преобразовать новые строки DOS/Windows в Unix?
dos2unix
и unix2dos
команды не доступны в определенных системах. Как я могу эмулировать их с командами как sed
/awk
/tr
?
Эту проблему можно решить стандартными средствами, но здесь достаточно много ловушек для несведущих, поэтому я рекомендую вам установить команду flip
, которая была написана более 20 лет назад Рахулом Дхези, автором zoo
.
Она отлично справляется с преобразованием форматов файлов, избегая, например, непреднамеренного уничтожения бинарных файлов, что слишком просто, если вы просто гоняетесь по округе, изменяя каждый CRLF, который видите...
tr -d "\r" < file
посмотрите здесь , чтобы увидеть примеры использования sed
:
# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format.
sed 's/.$//' # assumes that all lines end with CR/LF
sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//' # works on ssed, gsed 3.02.80 or higher
# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format.
sed "s/$/`echo -e \\\r`/" # command line under ksh
sed 's/$'"/`echo \\\r`/" # command line under bash
sed "s/$/`echo \\\r`/" # command line under zsh
sed 's/$/\r/' # gsed 3.02.80 or higher
Используйте sed -i
для преобразования на месте, например sed -i 's /..../' файл
.
Вы можете использовать tr
для преобразования из DOS в Unix; однако, вы можете сделать это безопасно, только если CR появляется в вашем файле только как первый байт пары байт CRLF. Обычно так и происходит. Затем вы используете:
tr -d '\015' <DOS-file >UNIX-file
Обратите внимание, что имя DOS-файл
отличается от имени UNIX-файл
; если вы попытаетесь использовать одно и то же имя дважды, в итоге в файле не будет данных.
Вы не можете сделать это наоборот (со стандартным 'tr').
Если вы знаете, как ввести возврат каретки в скрипт (control-V, control-M для ввода control-M), то:
sed 's/^M$//' # DOS to Unix
sed 's/$/^M/' # Unix to DOS
где '^M' - символ control-M. Вы также можете использовать механизм bash
ANSI-C Quoting для указания возврата каретки:
sed $'s/\r$//' # DOS to Unix
sed $'s/$/\r/' # Unix to DOS
Однако, если вам придется делать это очень часто (грубо говоря, более одного раза), гораздо разумнее установить программы преобразования (например, dos2unix
и unix2dos
, или, возможно, dtou
и utod
) и использовать их.
Решения, опубликованные на данный момент, решают только часть проблемы, преобразовывая CRLF DOS / Windows в LF Unix; часть, которой им не хватает, состоит в том, что DOS использует CRLF как разделитель строк , тогда как Unix использует LF как признак конца строки . Разница в том, что в файле DOS (обычно) ничего не будет после последней строки файла, в то время как в Unix это будет. Чтобы выполнить преобразование должным образом, вам нужно добавить этот последний LF (если файл не имеет нулевой длины, то есть вообще не содержит строк). Мое любимое заклинание для этого (с небольшой добавленной логикой для обработки файлов, разделенных CR в стиле Mac, а не приставания к файлам, которые уже находятся в формате unix) - это немного perl:
perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt
Обратите внимание, что это отправляет Unixified версию файл в стандартный вывод. Если вы хотите заменить файл версией Unixified, добавьте флаг perl -i
.
Используя AWK, вы можете:
awk '{ sub("\r$", ""); print }' dos.txt > unix.txt
Используя Perl, вы можете:
perl -pe 's/\r$//' < dos.txt > unix.txt