Удалить возврат каретки в Unix


Ответы:


261

Я буду считать , что вы имеете в виду возврат каретки ( CR, "\r", 0x0d) в концах строк , а не просто слепо в файле (вы можете иметь их в середине строки для всех я знаю). Используя этот тестовый файл только CRв конце первой строки:

$ cat infile
hello
goodbye

$ cat infile | od -c
0000000   h   e   l   l   o  \r  \n   g   o   o   d   b   y   e  \n
0000017

dos2unix это путь, если он установлен в вашей системе:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Если по какой-то причине вам dos2unixэто не доступно, то sedсделаем это:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Если по какой-то причине вам sedэто недоступно, то edсделаем это сложным образом:

$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Если на вашем компьютере не установлено ни одного из этих инструментов, у вас есть большие проблемы, чем при попытке конвертировать файлы :-)


13
\rработает только с GNU sed, иначе вы можете сделать это:sed `echo "s/\r//"`
Lapo

15
Ни в MacO, sedни в echoраспознавании \r. В этом случае только printf "\r"кажется, что работает.
Стив Пауэлл

30
Чтобы уточнить комментарий @ steve: На Mac используйте следующее: sed "s/$(printf '\r')\$//"
mklement0

7
Чтобы исправить проблему на Mac, вы также можете поставить префикс строки с одинарными кавычками $следующим образом: sed $'s@\r@@g' |od -c(но если вы замените ее, \nвам нужно ее избежать)
nhed

1
Я не уверен на 100%, но для OS X использование CTRL-V + CTRL-Mвместо \rпохоже, что это могло бы работать.

240
tr -d '\r' < infile > outfile

Смотрите tr (1)


4
Не здорово: 1. не работает на месте, 2. может заменить \ r также не в EOL (что может или не может быть то, что вы хотите ...).
Томаш Гандор

10
1. Большинство unixy-инструментов работают именно так, и, как правило, это самый безопасный способ решения проблем, поскольку, если вы облажаетесь, у вас остается оригинал. 2. Поставленный вопрос состоит в том, чтобы удалить возврат каретки, а не преобразовывать окончания строк. Но есть множество других ответов, которые могут помочь вам лучше.
Хенрик Густафссон

1
Если ваша trкоманда не поддерживает \rescape, попробуйте '\015'или, возможно, литерал '^M'(во многих оболочках на многих терминалах ctrl-V ctrl-M выдаст буквальный символ ctrl-M).
tripleee

Так как же изменить это, когда вы хотите outfile = infile?
Кристофер

3
@donlan, поздний ответ , но вы , как правило , использовать что - то вроде: someProg <in >out && mv out in.
paxdiablo


32

Самый простой способ для Linux, по моему скромному мнению,

sed -i 's/\r$//g' <filename>

В сильных кавычках вокруг оператора подстановок 's/\r//'являются существенными . Без них оболочка будет интерпретироваться \rкак escape + r, уменьшать ее до простого rи удалять все строчные буквы r. Вот почему ответ, данный Робом в 2009 году , не работает.

А добавление /gмодификатора гарантирует, что \rбудет удалено даже многократное число , а не только первое.


27

Существует утилита dos2unix, которая существует во многих системах и может быть легко установлена ​​в большинстве систем.


6
Иногда это также называется fromdos (и todos).
Аноним

Ссылка сейчас не работает, пожалуйста, посетите http://dos2unix.sourceforge.net/ вместо этого
RyanQuey

7

sed -i s/\r// <filename>или что-то подобное; увидеть man sedили множество информации, доступной в Интернете, относительно использования sed.

Следует отметить одно точное значение слова «возврат каретки» в приведенном выше; если вы действительно имеете в виду один управляющий символ «возврат каретки», то приведенная выше схема верна. Если вы имели в виду, в более общем смысле, CRLF (возврат каретки и перевод строки, то есть, как переводы строк реализованы в Windows), то вы, вероятно, хотите заменить \r\nвместо этого. Голые строки (новая строка) в Linux / Unix есть \n.


Я пытаюсь использовать -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt, который не работает. "тигр" "лев"
Сувасис

мы должны принять это, чтобы означать, что вы на Mac? Я заметил, что Darwin sed, по-видимому, имеет другие команды и наборы функций по умолчанию, чем большинство версий Linux ...
jsh

4
К вашему сведению, s/\r//похоже, что в OS X возврат каретки не rудаляется, вместо этого он, похоже, удаляет буквенные символы. Я не уверен, почему это еще. Может быть, это как-то связано со способом цитирования строки? Как обходной путь, использование CTRL-V + CTRL-Mвместо, \rкажется, работает.

6

Если вы являетесь пользователем Vi, вы можете открыть файл и удалить возврат каретки с помощью:

:%s/\r//g

или с

:1,$ s/^M//

Обратите внимание, что вы должны набрать ^ M, нажав Ctrl-V, а затем Ctrl-M.


2
Не очень хорошо: если файл имеет CR в каждой строке (то есть является правильным файлом DOS), vim загрузит его с filetype = dos, а не покажет ^M-s вообще. Обойти это - тонна нажатий клавиш, а это не то, для чего создан vim;). Я бы просто пошел sed -i, а затем `-e 's / \ r $ // g', чтобы ограничить удаление CRs на EOL.
Томаш Гандор

6

Еще раз решение ... Потому что всегда есть еще один:

perl -i -pe 's/\r//' filename

Это приятно, потому что он работает и работает в каждом варианте Unix / Linux, с которым я работал.


3

Кто-то еще рекомендует, dos2unixи я настоятельно рекомендую это также. Я просто предоставляю больше деталей.

Если установлено, перейдите к следующему шагу. Если он еще не установлен, я бы рекомендовал установить его через yum:

yum install dos2unix

Тогда вы можете использовать его как:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt

2

Если вы используете ОС (например, OS X), у которой нет dos2unixкоманды, но есть интерпретатор Python (версия 2.5+), эта команда эквивалентна dos2unixкоманде:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Это обрабатывает как именованные файлы в командной строке, так и каналы и перенаправления, как dos2unix. Если вы добавите эту строку в файл ~ / .bashrc (или эквивалентный файл профиля для других оболочек):

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

... при следующем входе в систему (или запуске source ~/.bashrcв текущем сеансе) вы сможете использовать dos2unixимя в командной строке так же, как и в других примерах.


2

Вот вещь,

%0dсимвол возврата каретки Сделать его совместимым с Unix. Нам нужно использовать приведенную ниже команду.

dos2unix fileName.extension fileName.extension


1

Попробуйте это преобразовать файл DOS в файл Unix:

файл fromdos


1

Для UNIX ... Я заметил, что dos2unix удалил заголовки Unicode из моего файла UTF-8. В git bash (Windows) следующий скрипт, похоже, работает хорошо. Он использует sed. Обратите внимание, что он удаляет только возврат каретки на концах строк и сохраняет заголовки Unicode.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"

1

Если вы работаете в среде X и имеете соответствующий редактор (код Visual Studio), я бы следовал рекомендациям:

Код Visual Studio: как показать окончания строк

Просто перейдите в правый нижний угол экрана, код Visual Studio покажет вам как кодировку файла, так и соглашение об окончании строки, за которым следует файл, простым щелчком мыши вы можете переключить его.

Просто используйте визуальный код в качестве замены для notepad ++ в среде Linux, и все готово.


Или используйте Notepad++команду в Edit / EOL Conversion / Unix (LF)вашей системе Windows перед копированием файла в вашу систему Linux.
Джесси Чисхолм

1

Удаление \rв любой системе UNIX®:

Большинство существующих решений в этом вопросе специфичны для GNU и не будут работать на OS X или BSD; приведенное ниже решение должно работать на многих других системах UNIX, и в любой оболочке, от tcshдо sh, но по- прежнему работать даже на GNU / Linux, тоже.

Протестировано на OS X, OpenBSD и NetBSD в tcshи на Debian GNU / Linux в bash.


С sed:

В tcshна OS X, следующий sedфрагмент кода может быть использована вместе с printf, так как ни , sedни echoручки \rособым способом , как ГНУ делает:

sed `printf 's/\r$//g'` input > output

С tr:

Другой вариант tr:

tr -d '\r' < input > output

Разница между sedи tr:

Казалось бы, что trсохраняет отсутствие завершающей новой строки из входного файла, тогда как sedв OS X и NetBSD (но не в OpenBSD или GNU / Linux) вставляет завершающую новую строку в самом конце файла, даже если во входных данных отсутствует какой-либо в конце \rили \nв самом конце файла.


Тестирование:

Вот несколько примеров тестирования, которые можно использовать, чтобы убедиться, что это работает в вашей системе, используя printfи hexdump -C; в качестве альтернативы, od -cможет также использоваться, если ваша система отсутствует hexdump:

% printf 'a\r\nb\r\nc' | hexdump -C
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
% 

0

Я использовал Python для этого, здесь мой код;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)

0

Хотя это старый пост, недавно я столкнулся с той же проблемой. Поскольку у меня были все файлы для переименования внутри / tmp / blah_dir /, так как каждый файл в этом каталоге имел символ «/ r» (в конце файла был символ «?»), Так что делать это способом сценария было только для меня.

Я хотел сохранить окончательный файл с тем же именем (без конечного символа). С sed проблема была в имени выходного файла, которое мне было необходимо, чтобы упомянуть что-то еще (чего я не хотел).

Я пробовал другие варианты, как предложено здесь (не считал dos2unix из-за некоторых ограничений), но не работал.

Наконец, я попытался с "awk", который работал, где я использовал "\ r" в качестве разделителя и взял первую часть :

Хитрость заключается в следующем:

echo ${filename}|awk -F"\r" '{print $1}'

Ниже приведен фрагмент сценария, который я использовал (где у меня все файлы имели «\ r» в качестве завершающего символа в пути / tmp / blah_dir /), чтобы исправить мою проблему:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

Примечание: этот пример не очень точен, хотя и близок к тому, что я работал (упомяну здесь, чтобы дать лучшее представление о том, что я сделал)


0

Я сделал этот shell-скрипт для удаления символа \ r. Работает в солярисе и красной шапке:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0

-1

Вы можете просто сделать это:

$ echo $(cat input) > output

Не знаю, почему кто-то дал «-1». Это очень хороший ответ (и единственный, который работал на меня).
FractalSpace

1
Ой, прости, это был я. Подождите, смотрите, это действительно не работает для '\ r'!
Вячеслав Родионов

1
@FractalSpace Это ужасная идея! Он полностью разрушает весь интервал в файле и оставляет все содержимое файла для интерпретации оболочкой. Попробуйте это с файлом, который содержит одну строку a * b...
Том Фенек
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.