Как преобразовать DOS или Windows перевод строки (возврата каретки и перевода строки) в Unix перевод строки (LF) в bash-скрипт?




Ответы - Как преобразовать DOS или Windows перевод строки (возврата каретки и перевода строки) в Unix перевод строки (LF) в bash-скрипт? / How to convert DOS/Windows newline (CRLF) to Unix newline (LF) in a Bash script?


решение awk.

10.04.2010 07:13:36
Вы можете использовать tr
для преобразования из DOS в Unix; однако вы можете сделать это безопасно только в том случае, если CR появляется в вашем файле только как первый байт пары байтов CRLF. Так обычно и бывает. Затем вы используете:
tr -d '\015' <DOS-file >UNIX-file
Обратите внимание, что имя DOS-file
отличается от имени UNIX-file
; если вы попытаетесь использовать одно и то же имя дважды, вы не получите никаких данных в файле.
Вы не можете сделать это наоборот (со стандартным '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
) и использовать их.

tr -d '\015' <DOS-file >UNIX-file
, где DOS-file
== UNIX-file
просто результаты в пустой файл. К сожалению, выходной файл должен быть другим файлом.



sed
(для in-place); ограничения представляют собой связанные файлы и символические ссылки. Команда -i
"всегда" (с 1979 года, если не раньше) поддерживает опциюsort
, которая может выводить список одного из входных файлов. Однако отчасти это связано с тем, что -o
должен прочитать все свои входные данные, прежде чем он сможет записать любой из своих выходных данных. Другие программы периодически поддерживают перезапись одного из своих входных файлов. Вы можете найти программу общего назначения (скрипт), чтобы избежать проблем в "среде программирования UNIX" Kernighan & Pike.

sed -i $'s/\r$//' filename
-для редактирования на месте. Я работаю на машине, которая не имеет доступа к интернету, поэтому установка программного обеспечения является проблемой.

tr -d '\015' < original_file > t && mv t original_file
- в основном работает, создавая временный файл, а затем перезаписывая им старый.

sed
не делает (по умолчанию, не уверен, что вы можете это изменить?) признать сбежал версий \r
, \015
, \x0d
для возврата каретки; sed
признает КЛ при вводе с ctrl-v ctrl-m
, как описано выше (



find
, чтобы определить файлы, которые нужно изменить (или создать список имен файлов — один надеется, что они не должны содержать пробелов и прочих непокорных препинания в названиях), а затем применить скрипт в архиве. Используя find … -exec sh script.sh {} +
является довольно эффективным. Альтернатив-легион. Техника find
работает с абсурдными именами.

10.04.2010 07:21:05
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/..../' file
.


-d
используется чаще и не поможет в ситуации "только \r
".

\r
\n
имеет эффект двойного интервала между файлами; каждая отдельная строка CRLF, заканчивающаяся в DOS, становится \n\n
в Unix.


10.04.2010 09:50:06
Решения, опубликованные до сих пор, касаются только части проблемы , преобразования CRLF DOS/Windows в LF Unix; часть, которую они упускают, состоит в том, что DOS использует CRLF в качестве разделителя строк, в то время как Unix использует LF в качестве Терминатора строк . Разница в том, что файл DOS (обычно) не будет иметь ничего после последней строки в файле, в то время как Unix будет. Чтобы правильно провести конвертацию, вам необходимо добавить этот final 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 версию файла в stdout. Если вы хотите заменить файл на Unixified версию, добавьте флаг perl-i
.



11.04.2010 02:32:46
Эта проблема может быть решена с помощью стандартных инструментов, но есть достаточно много ловушек для неосторожных, что я рекомендую вам установить команду flip
, которая была написана более 20 лет назад Рахулом Дхеси, автором zoo
.
Он отлично справляется с преобразованием форматов файлов, например, избегая непреднамеренного уничтожения двоичных файлов, что немного слишком легко, если вы просто гоняетесь вокруг изменения каждого CRLF, который вы видите...




10.09.2013 05:08:27
Я пытался sed' s/^M$// ' файл.формат txt на OSX, а также несколько других методов ( http://www.thingy-ma-jig.co.uk/blog/25-11-2010/fixing-dos-line-endings или http://hintsforums.macworld.com/archive/index.php/t-125.html ). никто не работал, файл оставался неизменным (кстати Ctrl-v Enter был необходим для воспроизведения ^M). В конце концов я использовал TextWrangler. Это не совсем командная строка, но она работает и не жалуется.

31.10.2013 01:40:43
Если у вас нет доступа к dos2unix, но вы можете прочитать эту страницу, то вы можете скопировать / вставить dos2unix.py отсюда.
#!/usr/bin/env python
"""\
convert dos linefeeds (crlf) to unix (lf)
usage: dos2unix.py <input> <output>
"""
import sys
if len(sys.argv[1:]) != 2:
sys.exit(__doc__)
content = ''
outsize = 0
with open(sys.argv[1], 'rb') as infile:
content = infile.read()
with open(sys.argv[2], 'wb') as output:
for line in content.splitlines():
outsize += len(line) + 1
output.write(line + '\n')
print("Done. Saved %s bytes." % (len(content)-outsize))
Кросс-пост от суперпользователя .

dos2unix
преобразует все входные файлы по умолчанию. Ваше использование подразумевает -n
-это фильтр, который читает из stdin, записывает в stdout, если файлы не заданы.

30.04.2014 02:02:31
Делать это с POSIX сложно:
POSIX Sed не поддерживает
\r
или\15
. Даже если и так, то на месте option-i
не является POSIXPOSIX Awk поддерживает
\r
и\15
, однако опция-i inplace
это не POSIXd2u и dos2unix-это не утилиты POSIX, а ex
POSIX ex не поддерживает
\r
,\15
,\n
или\12
Чтобы удалить возврат каретки:
ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file
Чтобы добавить возврат каретки:
ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file

tr
поддерживает \r
. Так что вы можете также использовать printf '%s\n' '%!tr -d "\r"' x | ex file
(хотя и разрешено, это удалено \r
, даже если не непосредственно предшествует \n
). Кроме того, параметр-b
для ex
не указан в POSIX.


20.05.2014 03:25:59
Для Mac osx, если у вас установлен homebrew [ http://brew.sh/][1]
brew install dos2unix
for csv in *.csv; do dos2unix -c mac ${csv}; done;
Убедитесь, что вы сделали копии файлов, так как эта команда изменит файлы на месте. Опция-C для Mac делает переключатель для совместимости с OSX.


-c mac
, который предназначен для преобразования CR
CR. Вы хотите использовать этот режим только для файлов на Mac OS 9 и выше.

04.09.2014 04:16:46
Еще более простое решение awk без программы:
awk -v ORS='\r\n' '1' unix.txt > dos.txt
Технически "1" - это ваша программа, b/c awk требует одного, когда дается опция.
Обновление: После повторного просмотра этой страницы в первый раз за долгое время я понял, что никто еще не опубликовал внутреннее решение, так что вот один:
while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt


awk -v RS='\r\n' '1' dos.txt > unix.txt



awk
или sed
. Кроме того, вы должны использовать while IFS= read -r line
, чтобы точно сохранить входные строки, иначе начальные и конечные пробелы будут обрезаны (в качестве альтернативы, не используйте имя переменной в команде read
и работайте с $REPLY
).

$READ
), чтение просто разбивается на концовки строк, и вы можете просто использовать echo вместо printf (echo, скорее всего, будет встроенным, и это обычно быстрее). Итак, используя ctrl-v+ctrl-m для ввода \r, можно просто сделать while read -r; do echo "${REPLY%^M}"; done < file > file.fixed
, и это примерно та же скорость, что и sed.



30.07.2015 08:38:45
Супер пупер легко с PCRE;
Как скрипт, или замените $@
вашими файлами.
#!/usr/bin/env bash
perl -pi -e 's/\r\n/\n/g' -- $@
Это перезапишет ваши файлы на месте!
Я рекомендую делать это только с резервной копией (контроль версий или иначе)

--
Я выбрал это решение, потому что его легко понять и адаптировать для меня. К вашему сведению, это то, что делают коммутаторы: -p
принимает цикл" while input", -i
редактирует входной файл на месте, -e
выполняет следующую команду



07.11.2016 02:30:31
Вы можете использовать awk. Установите разделитель записей ( RS
) в регулярное выражение, которое соответствует всем возможным символам новой строки или символам. И установите разделитель выходных записей (ORS
) на символ новой строки в стиле unix.
awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt

git diff
shows ^M, отредактировано в vim)


23.06.2017 09:37:19
Пришлось просто задуматься над тем же вопросом (на стороне Windows, но в равной степени применимо и к linux.)
Удивительно, что никто не упомянул об очень автоматизированном способе преобразования CRLF< - >LF для текстовых файлов, использующем старый добрый zip -ll
(Info-ZIP):
zip -ll textfiles-lf.zip files-with-crlf-eol.*
unzip textfiles-lf.zip
Примечание: это создаст zip-файл с сохранением исходных имен файлов, но преобразованием окончаний строк в LF. Затем unzip
извлекает файлы в виде zip'Ed, то есть с их оригинальными именами (но с LF-окончаниями), таким образом предлагая перезаписать локальные исходные файлы, если таковые имеются.
Соответствующая выдержка из zip --help
:
zip --help
...
-l convert LF to CR LF (-ll CR LF to LF)

21.07.2017 12:21:05
интересно, что в моем git-bash на windows sed ""
уже сделали свое дело:
$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text
Я предполагаю, что sed игнорирует их при чтении строк из ввода и всегда записывает окончания строк unix на выходе.

13.07.2018 04:43:14
В Linux легко конвертировать ^M (ctrl-M) в * Nix newlines (^J) с помощью sed.
Это будет что-то вроде этого на CLI, там на самом деле будет разрыв строки в тексте. Однако \ передает это ^J вместе с sed:
sed 's/^M/\
/g' < ffmpeg.log > new.log
Вы получите это с помощью ^V (ctrl-V), ^M (ctrl-M) и \ (обратная косая черта) при вводе:
sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log


18.07.2018 03:34:31
Для преобразования файла на месте используйте
dos2unix <filename>
Для вывода преобразованного текста в другой файл используйте
dos2unix -n <input-file> <output-file>
Вы можете установить его на Ubuntu или Debian с
sudo apt install dos2unix
или на macOS с использованием homebrew
brew install dos2unix


31.08.2018 01:03:11
Vim можно использовать программно с помощью команды option-c {} :
Dos в Unix:
vim file.txt -c "set ff=unix" -c ":wq"
Unix to dos:
vim file.txt -c "set ff=dos" -c ":wq"
"set ff=unix / dos" означает изменение fileformat (ff) файла на Unix / DOS формат конца строки
": wq " означает запись файла на диск и выход из редактора (что позволяет использовать команду в цикле)


vi
, будет знать, что
означает: wq. Для тех, кто этого не делает, 3 символа означают 1) Открыть командную область vi, 2) написать и 3) выйти.



18.10.2018 05:51:19
sed --expression='s/\r\n/\n/g'
Поскольку в вопросе упоминается sed, это самый прямой способ использовать sed для достижения этой цели. Выражение говорит следующее: замените все возвраты каретки и перевод строки только на перевод строки. Это то, что вам нужно, когда вы переходите от Windows к Unix. Я проверил, что это работает.


12.02.2019 12:48:08
Я сделал скрипт, основанный на принятом ответе, так что вы можете конвертировать его напрямую, не нуждаясь в дополнительном файле в конце, а затем удалить и переименовать.
convert-crlf-to-lf() {
file="$1"
tr -d '\015' <"$file" >"$file"2
rm -rf "$file"
mv "$file"2 "$file"
}
просто убедитесь, что у вас есть файл типа "file1.txt "that" file1.txt2 " еще не существует или будет перезаписан,я использую его как временное место для хранения файла.