Видаліть повернення каретки в 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
Ні, sedні echoрозпізнавати \rна MacO. У цьому випадку, printf "\r"здається, працює.
Стів Пауелл

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

7
Для випуску виправлень на макінтош ви також можете випередити одиничні лапки SED рядок $наступним чином: 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. може замінити також не EOL (що може бути, а може і не бути тим, що ви хочете ...).
Томаш Гандор

10
1. Більшість уніфікованих інструментів працює таким чином, і зазвичай це найбезпечніший спосіб робити речі, оскільки якщо ви накрутите, у вас все ще є оригінал. 2. Поставлене питання полягає в тому, щоб видалити повернення перевезення, а не конвертувати закінчення рядків. Але є багато інших відповідей, які можуть вам краще служити.
Генрік Густафссон

1
Якщо ваш trне підтримує \rвтечу, спробуйте '\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буде видалено, і не тільки перший.



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? Я помітив, що, здається, у Дарвіна sed за замовчуванням є різні команди та набори функцій, ніж більшість версій Linux ...
jsh,

4
FYI, 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 завантажує його у файлі = dos, а не відображається ^M-s. Подолати це - тона натискань на клавіші, яка не для чого зроблена; Я б просто пішов на sed -i, а потім `-e 's / \ r $ // g', щоб обмежити видалення на CR в 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

Для 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: Як показати закінчення рядків

Просто перейдіть до правого нижнього кута екрана, візуальний код студії покаже вам кодування файлу та закінчення конвенції рядка з подальшим файлом, просто за допомогою простого клацання ви можете переключити це навколо.

Просто використовуйте візуальний код як заміну для блокнота ++ у середовищі 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:

У tcshOS X наступний sedфрагмент може використовуватися разом із printf, як ні, sedні echoобробляти \rспеціальним чином, як це робить GNU:

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

Я створив цей скрипт оболонки, щоб видалити символ \ 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.