В общем, просто установите dos2unixс помощью менеджера пакетов, это действительно намного проще и существует на большинстве платформ.
Брэд Кох
1
Согласовано! @BradKoch Простой как «brew install dos2unix» на Mac OSX
SmileIT
Ответы:
323
Вы можете использовать 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, чтобы указать возврат каретки:
sed $'s/\r$//'# DOS to Unix
sed $'s/$/\r/'# Unix to DOS
Однако, если вам придется делать это очень часто (более одного раза, грубо говоря), гораздо разумнее установить программы преобразования (например, dos2unixи unix2dos, или, возможно, dtouи utod) и использовать их.
Если вам нужно обработать целые каталоги и подкаталоги, вы можете использовать zip:
zip -r -ll zipfile.zip somedir/
unzip zipfile.zip
Это создаст zip-архив с окончаниями строк, измененными с CRLF на CR. unzipзатем вернет преобразованные файлы обратно на место (и спросит вас файл за файлом - вы можете ответить: Да для всех). Кредиты @vmsnomad для указания на это.
использование tr -d '\015' <DOS-file >UNIX-filewhere DOS-file== UNIX-fileпросто приводит к пустому файлу. Выходной файл, к сожалению, должен быть другим файлом.
Баттл Буткус
3
@ButtleButkus: ну да; Вот почему я использовал два разных имени. Если вы запакуете входной файл до того, как программа все его прочитает, как вы это делаете, когда дважды используете одно и то же имя, вы получите пустой файл. Это единообразное поведение в Unix-подобных системах. Требуется специальный код для безопасной перезаписи входного файла. Следуйте инструкциям, и все будет в порядке.
Джонатан Леффлер
Кажется, я помню некоторые функции поиска-замены в файле.
Баттл Буткус
4
Есть места; Вы должны знать, где их найти. В определенных пределах работает sedопция GNU -i(на месте); пределы - это связанные файлы и символические ссылки. sortКоманда имеет «всегда» (с 1979 года, если не раньше) поддерживает -oвариант , который может перечислить один из входных файлов. Однако это отчасти потому, что sortнеобходимо прочитать все входные данные, прежде чем он сможет записать любой из своих выходных данных. Другие программы время от времени поддерживают перезапись одного из своих входных файлов. Вы можете найти программу общего назначения (скрипт), чтобы избежать проблем в «Среде программирования UNIX» от Kernighan & Pike.
Джонатан Леффлер
3
Третий вариант у меня сработал, спасибо. Я использовал опцию -i: sed -i $'s/\r$//' filename- для редактирования на месте. Я работаю на машине, у которой нет доступа к Интернету, поэтому проблема с установкой программного обеспечения.
# 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.
Я использовал вариант, так как мой файл имел только \r:tr "\r" "\n" < infile > outfile
Мэтт Тодд
1
@MattTodd не могли бы вы опубликовать это как ответ? -dхарактеризуется более часто и не поможет в «только \r» ситуации.
n611x007
5
Следует отметить , что предлагаемое \rв \nотображении имеет эффект двойной интервал файлов; каждая строка CRLF, заканчивающаяся в DOS, становится \n\nв Unix.
Джонатан Леффлер
Могу ли я сделать это рекурсивно?
Аарон Франке
36
Делать это с POSIX сложно:
POSIX Sed не поддерживает \rили \15. Даже если это так, опция на месте -iне POSIX
POSIX Awk поддерживает \rи \15, однако, -i inplaceопция не POSIX
Похоже, поддерживает POSIX . tr\r Таким образом, вы также можете использовать printf '%s\n' '%!tr -d "\r"' x | ex file(хотя и предоставлено, это удалено, \rдаже если не предшествует непосредственно \n). Кроме того, -bопция exне указана в POSIX.
Wildcard
1
Делать это в POSIX легко. Вставьте CR-литерал в скрипт, набрав его (это control-M).
Джошуа
28
Вы можете использовать vim программно с опцией -c {команда}:
Дос в 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» означает изменить формат файла (ff) файла на формат конца строки Unix / DOS
«: wq» означает запись файла на диск и выход из редактора (что позволяет использовать команду в цикле)
Это казалось самым элегантным решением, но отсутствие объяснения того, что означает wq, вызывает сожаление.
Джоррик Слейстер
5
Любой, кто использует, viбудет знать, что :wqзначит. Для тех, кто не использует 3 символа, это означает 1) открытая область команд vi, 2) запись и 3) выход.
Дэвид Ньюкомб
Я понятия не имел, что вы могли бы интерактивно добавлять команды в vim из CLI
Я знаю, что вопрос требует альтернативы dos2unix, но это первый результат Google.
Борис
18
Эту проблему можно решить стандартными инструментами, но для неосторожных достаточно ловушек, поэтому я рекомендую вам установить flipкоманду, написанную более 20 лет назад Рахулом Дези, автором zoo. Он отлично справляется с преобразованием форматов файлов, например, избегая непреднамеренного уничтожения двоичных файлов, что будет слишком легко, если вы просто мчитесь вокруг изменения каждого CRLF, который вы видите ...
У меня был опыт взлома половины моей ОС, просто запустив texxto с неправильным флагом. Будьте осторожны, особенно если вы хотите сделать это на целых папках.
A_P
14
Опубликованные на данный момент решения касаются только части проблемы, превращая CRLF DOS / Windows в LF Unix; часть, которую они пропускают, состоит в том, что DOS использует CRLF в качестве разделителя строк , в то время как Unix использует LF в качестве ограничителя строки . Разница в том, что файл DOS (обычно) не будет иметь ничего после последней строки в файле, в то время как Unix будет. Чтобы правильно выполнить преобразование, вам нужно добавить этот последний LF (если только файл не имеет нулевой длины, то есть не содержит строк). Мое любимое заклинание для этого (с небольшой добавленной логикой для обработки файлов в стиле Mac в стиле CR, а не для файлов, которые уже находятся в формате unix) - это немного perl:
Обратите внимание, что это отправляет Unixified версию файла на стандартный вывод. Если вы хотите заменить файл на Unixified версию, добавьте -iфлаг perl .
@LudovicZenohateLagouardette Был ли это простой текстовый файл (т. Е. CSV или разделенный табуляцией текст) или что-то еще? Если он был в каком-то формате базы данных, манипулирование им, как будто это был текст, очень вероятно, повредит его внутреннюю структуру.
Гордон Дэвиссон
Простой текст CSV, но я думаю, что завершение было странным. Я думаю, что это испортилось из-за этого. Однако не волнуйтесь. Я всегда собираю резервные копии, и это был даже не настоящий набор данных, а всего лишь 1 ГБ. Настоящий 26 ГБ.
Людовик Зенохате Лагуардетт
14
Если у вас нет доступа к 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параметр. И реальным dos2unixявляется фильтр, который читает из стандартного ввода, пишет в стандартный вывод, если файлы не передаются.
Спасибо! Это работает, хотя я пишу имя файла и нет --. Я выбрал это решение, потому что его легко понять и адаптировать для меня. К вашему сведению, это то, что делают переключатели: -pпредположим цикл «во время ввода», -iотредактируем входной файл на месте, -eвыполним следующую команду
Rolf
Строго говоря, PCRE - это переопределение движка регулярных выражений Perl, а не движка регулярных выражений от Perl. У них обоих есть такая возможность, хотя есть и различия, несмотря на смысл в названии.
tripleee
6
Еще более простое решение 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
Это удобно, но для ясности: это переводит Unix -> Windows / DOS, что противоположно тому, о чем просил OP.
mklement0
5
Это было сделано специально, оставлено в качестве упражнения для автора. eyerollsawk -v RS='\r\n' '1' dos.txt > unix.txt
nawK
Отлично (и слава тебе за педагогическое изящество).
mklement0
1
"b / c awk требует один, когда дана опция." - awk всегда требует программу, независимо от того, указаны параметры или нет.
mklement0
1
Чистое решение Bash интересно, но гораздо медленнее, чем эквивалент awkили sedрешение. Кроме того, вы должны использовать while IFS= read -r lineдля точного сохранения строк ввода, в противном случае начальные и конечные пробелы обрезаются (в качестве альтернативы, не используйте имя переменной в readкоманде и работайте с ней $REPLY).
mklement0
5
Просто задумался над тем же вопросом (на стороне 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)
Этот ответ на самом деле не вопрос оригинального постера.
hlin117
2
Пользователи OS X не должны использовать -c mac, то есть для преобразования pre-OS X CR- только переводы строк. Вы хотите использовать этот режим только для файлов в и из Mac OS 9 или ранее.
askewchan
2
TIMTOWTDI!
perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof'PCfile.txt
Вы можете использовать awk. Установите разделитель записей ( RS) в регулярное выражение, которое соответствует всем возможным символам новой строки или символам. И установите разделитель выходной записи ( ORS) на символ новой строки в стиле Unix.
Поскольку в вопросе упоминается sed, это самый простой способ использовать sed для достижения этой цели. Выражение говорит, что все возвраты каретки и перевода строки заменяются только переводом строки. Это то, что вам нужно, когда вы переходите с Windows на Unix. Я проверил это работает.
Привет, Джон Пол - этот ответ был помечен для удаления, поэтому я попал в очередь на проверку. В общем, когда у вас есть такой вопрос, которому 8 лет, с 22 ответами, вы захотите объяснить, насколько ваш ответ полезен, чем другие существующие ответы.
zzxyz
0
В качестве расширения решения Jonathan Leffler для Unix to DOS можно безопасно конвертировать в DOS, когда вы не уверены в конце строки файла:
sed '/^M$/! s/$/^M/'
Это проверяет, что строка еще не заканчивается CRLF перед преобразованием в CRLF.
Я сделал скрипт на основе принятого ответа, чтобы вы могли конвертировать его напрямую, без необходимости в дополнительном файле в конце, а затем удалять и переименовывать.
Просто убедитесь, что если у вас есть файл типа «file1.txt», которого «file1.txt2» не существует, или он будет перезаписан, я использую его как временное место для хранения файла.
dos2unix
с помощью менеджера пакетов, это действительно намного проще и существует на большинстве платформ.Ответы:
Вы можете использовать
tr
для преобразования из DOS в Unix; однако вы можете сделать это безопасно только в том случае, если CR появляется в вашем файле только в качестве первого байта пары байтов CRLF. Обычно это так. Затем вы используете:Обратите внимание, что имя
DOS-file
отличается от имениUNIX-file
; если вы попытаетесь использовать одно и то же имя дважды, у вас не будет данных в файле.Вы не можете сделать это наоборот (со стандартным 'tr').
Если вы знаете, как ввести возврат каретки в скрипт ( control-V, control-Mчтобы ввести control-M), то:
где '^ M' является символом control-M. Вы также можете использовать механизм
bash
цитирования ANSI-C, чтобы указать возврат каретки:Однако, если вам придется делать это очень часто (более одного раза, грубо говоря), гораздо разумнее установить программы преобразования (например,
dos2unix
иunix2dos
, или, возможно,dtou
иutod
) и использовать их.Если вам нужно обработать целые каталоги и подкаталоги, вы можете использовать
zip
:Это создаст zip-архив с окончаниями строк, измененными с CRLF на CR.
unzip
затем вернет преобразованные файлы обратно на место (и спросит вас файл за файлом - вы можете ответить: Да для всех). Кредиты @vmsnomad для указания на это.источник
tr -d '\015' <DOS-file >UNIX-file
whereDOS-file
==UNIX-file
просто приводит к пустому файлу. Выходной файл, к сожалению, должен быть другим файлом.sed
опция GNU-i
(на месте); пределы - это связанные файлы и символические ссылки.sort
Команда имеет «всегда» (с 1979 года, если не раньше) поддерживает-o
вариант , который может перечислить один из входных файлов. Однако это отчасти потому, чтоsort
необходимо прочитать все входные данные, прежде чем он сможет записать любой из своих выходных данных. Другие программы время от времени поддерживают перезапись одного из своих входных файлов. Вы можете найти программу общего назначения (скрипт), чтобы избежать проблем в «Среде программирования UNIX» от Kernighan & Pike.sed -i $'s/\r$//' filename
- для редактирования на месте. Я работаю на машине, у которой нет доступа к Интернету, поэтому проблема с установкой программного обеспечения.посмотрите здесь примеры использования
sed
:Используйте
sed -i
для преобразования на месте, напримерsed -i 's/..../' file
.источник
\r
:tr "\r" "\n" < infile > outfile
-d
характеризуется более часто и не поможет в «только\r
» ситуации.\r
в\n
отображении имеет эффект двойной интервал файлов; каждая строка CRLF, заканчивающаяся в DOS, становится\n\n
в Unix.Делать это с POSIX сложно:
POSIX Sed не поддерживает
\r
или\15
. Даже если это так, опция на месте-i
не POSIXPOSIX Awk поддерживает
\r
и\15
, однако,-i inplace
опция не POSIXd2u и dos2unix не POSIX утилит , но бывший есть
POSIX бывший не поддерживает
\r
,\15
,\n
или\12
Чтобы удалить возврат каретки:
Чтобы добавить возврат каретки:
источник
tr
\r
Таким образом, вы также можете использоватьprintf '%s\n' '%!tr -d "\r"' x | ex file
(хотя и предоставлено, это удалено,\r
даже если не предшествует непосредственно\n
). Кроме того,-b
опцияex
не указана в POSIX.Вы можете использовать vim программно с опцией -c {команда}:
Дос в Unix:
Unix to dos:
«set ff = unix / dos» означает изменить формат файла (ff) файла на формат конца строки Unix / DOS
«: wq» означает запись файла на диск и выход из редактора (что позволяет использовать команду в цикле)
источник
vi
будет знать, что:wq
значит. Для тех, кто не использует 3 символа, это означает 1) открытая область команд vi, 2) запись и 3) выход.Используя AWK, вы можете сделать:
Используя Perl вы можете сделать:
источник
awk
решение.Чтобы конвертировать файл на месте, используйте
Для вывода преобразованного текста в другой файл используйте
Вы можете установить его на Ubuntu или Debian с помощью
или на macOS с помощью доморощенного
источник
Эту проблему можно решить стандартными инструментами, но для неосторожных достаточно ловушек, поэтому я рекомендую вам установить
flip
команду, написанную более 20 лет назад Рахулом Дези, авторомzoo
. Он отлично справляется с преобразованием форматов файлов, например, избегая непреднамеренного уничтожения двоичных файлов, что будет слишком легко, если вы просто мчитесь вокруг изменения каждого CRLF, который вы видите ...источник
Опубликованные на данный момент решения касаются только части проблемы, превращая CRLF DOS / Windows в LF Unix; часть, которую они пропускают, состоит в том, что DOS использует CRLF в качестве разделителя строк , в то время как Unix использует LF в качестве ограничителя строки . Разница в том, что файл DOS (обычно) не будет иметь ничего после последней строки в файле, в то время как Unix будет. Чтобы правильно выполнить преобразование, вам нужно добавить этот последний LF (если только файл не имеет нулевой длины, то есть не содержит строк). Мое любимое заклинание для этого (с небольшой добавленной логикой для обработки файлов в стиле Mac в стиле CR, а не для файлов, которые уже находятся в формате unix) - это немного perl:
Обратите внимание, что это отправляет Unixified версию файла на стандартный вывод. Если вы хотите заменить файл на Unixified версию, добавьте
-i
флаг perl .источник
Если у вас нет доступа к dos2unix , но вы можете прочитать эту страницу, то вы можете скопировать / вставить dos2unix.py отсюда.
Кросс-пост от суперпользователя .
источник
dos2unix
конвертирует все входные файлы по умолчанию. Ваше использование подразумевает-n
параметр. И реальнымdos2unix
является фильтр, который читает из стандартного ввода, пишет в стандартный вывод, если файлы не передаются.Супер пупер легко с PCRE;
В качестве сценария или заменить
$@
ваши файлы.источник
--
. Я выбрал это решение, потому что его легко понять и адаптировать для меня. К вашему сведению, это то, что делают переключатели:-p
предположим цикл «во время ввода»,-i
отредактируем входной файл на месте,-e
выполним следующую командуЕще более простое решение awk без программы:
Технически, «1» - это ваша программа, b / c awk требует ее при данной опции.
ОБНОВЛЕНИЕ : После повторного посещения этой страницы впервые за долгое время я понял, что никто еще не опубликовал внутреннее решение, поэтому вот одно:
источник
awk -v RS='\r\n' '1' dos.txt > unix.txt
awk
илиsed
решение. Кроме того, вы должны использоватьwhile IFS= read -r line
для точного сохранения строк ввода, в противном случае начальные и конечные пробелы обрезаются (в качестве альтернативы, не используйте имя переменной вread
команде и работайте с ней$REPLY
).Просто задумался над тем же вопросом (на стороне Windows, но в равной степени применим к linux.) Удивительно, что никто не упомянул об очень автоматизированном способе преобразования CRLF <-> LF для текстовых файлов с использованием старой доброй
zip -ll
опции (Info-ZIP):ПРИМЕЧАНИЕ: это создаст zip-файл, сохраняющий исходные имена файлов, но преобразующий окончания строк в LF. Затем
unzip
извлекает файлы как zip'ed, то есть с их оригинальными именами (но с LF-окончаниями), таким образом, предлагая перезаписать локальные исходные файлы, если таковые имеются.Соответствующая выдержка из
zip --help
:источник
интересно в моем git-bash на windows уже
sed ""
сделали свое дело :Я предполагаю, что sed игнорирует их при чтении строк с ввода и всегда записывает окончания строк Unix на выходе.
источник
Это сработало для меня
источник
Для Mac OSX, если у вас установлен homebrew [ http://brew.sh/][1]
Убедитесь, что вы сделали копии файлов, так как эта команда изменит файлы на месте. Опция -c mac делает этот переключатель совместимым с osx.
источник
-c mac
, то есть для преобразования pre-OS XCR
- только переводы строк. Вы хотите использовать этот режим только для файлов в и из Mac OS 9 или ранее.TIMTOWTDI!
Основано на @GordonDavisson
Надо учитывать возможность
[noeol]
...источник
Вы можете использовать awk. Установите разделитель записей (
RS
) в регулярное выражение, которое соответствует всем возможным символам новой строки или символам. И установите разделитель выходной записи (ORS
) на символ новой строки в стиле Unix.источник
git diff
показывает ^ M, отредактировано в VIM)В Linux легко конвертировать ^ M (ctrl-M) в * nix переводы строк (^ J) с помощью sed.
Это будет примерно так в CLI, на самом деле в тексте будет разрыв строки. Тем не менее, \ передает это ^ J вместе с sed:
Вы получаете это, используя ^ V (ctrl-V), ^ M (ctrl-M) и \ (обратную косую черту) при вводе:
источник
Поскольку в вопросе упоминается sed, это самый простой способ использовать sed для достижения этой цели. Выражение говорит, что все возвраты каретки и перевода строки заменяются только переводом строки. Это то, что вам нужно, когда вы переходите с Windows на Unix. Я проверил это работает.
источник
В качестве расширения решения Jonathan Leffler для Unix to DOS можно безопасно конвертировать в DOS, когда вы не уверены в конце строки файла:
Это проверяет, что строка еще не заканчивается CRLF перед преобразованием в CRLF.
источник
Я сделал скрипт на основе принятого ответа, чтобы вы могли конвертировать его напрямую, без необходимости в дополнительном файле в конце, а затем удалять и переименовывать.
Просто убедитесь, что если у вас есть файл типа «file1.txt», которого «file1.txt2» не существует, или он будет перезаписан, я использую его как временное место для хранения файла.
источник
В bash 4.2 и новее вы можете использовать что-то вроде этого для удаления конечного CR, который использует только встроенные bash:
источник
Я попробовал файл sed 's / ^ M $ //' для OSX, а также несколько других методов ( http://www.thingy-ma-jig.co.uk/blog/25-11-2010/fixing- Окончание дос-линии или http://hintsforums.macworld.com/archive/index.php/t-125.html ). Ничего не сработало, файл остался без изменений (например, Ctrl-v Enter был необходим для воспроизведения ^ M). В конце концов я использовал TextWrangler. Это не строго командная строка, но она работает и не жалуется.
источник