Який найпростіший спосіб видалити всі повернення каретки \r
з файлу в Unix?
Який найпростіший спосіб видалити всі повернення каретки \r
з файлу в Unix?
Відповіді:
Я буду вважати , що ви маєте в виду повернення каретки ( 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
Якщо у вас на коробці не встановлено жодного із цих інструментів, у вас є більші проблеми, ніж спроба конвертувати файли :-)
\r
працює лише з GNU sed, інакше ви можете це зробити:sed `echo "s/\r//"`
sed
ні echo
розпізнавати \r
на MacO. У цьому випадку, printf "\r"
здається, працює.
sed "s/$(printf '\r')\$//"
$
наступним чином: sed $'s@\r@@g' |od -c
(а якби замінити \n
вам буде потрібно , щоб уникнути його)
tr -d '\r' < infile > outfile
Див. Tr (1)
tr
не підтримує \r
втечу, спробуйте '\015'
або, можливо, літерал '^M'
(у багатьох оболонках на багатьох терміналах ctrl-V ctrl-M видасть буквальний символ ctrl-M).
outfile = infile
?
someProg <in >out && mv out in
.
На мій скромний погляд, найпростіший спосіб роботи в Linux -
sed -i 's/\r$//g' <filename>
У сильних лапках навколо оператора підстановок 's/\r//'
є суттєвими . Без них оболонка буде інтерпретувати \r
як escape + r і зменшить її до звичайної r
, і видалить всі малі регістри r
. Ось чому відповідь, дану вище у 2009 році Робом , не працює.
А додавання /g
модифікатора гарантує, що навіть декілька \r
буде видалено, і не тільки перший.
sed -i s/\r// <filename>
або дещо; Перегляньте man sed
чи багату інформацію, доступну в Інтернеті щодо використання sed
.
Одне, що слід зазначити, є точне значення "повернення вагона" у вищесказаному; якщо ви справді маєте на увазі єдиний керуючий символ "повернення вагона", то наведена вище схема є правильною. Якщо ви мали на увазі, загалом, CRLF (повернення каретки та канал рядка, яким чином реалізуються канали ліній під Windows), то ви, ймовірно, хочете замінити їх \r\n
. Головні канали (новий рядок) в Linux / Unix є \n
.
Якщо ви користувач Vi, ви можете відкрити файл і видалити повернення каретки за допомогою:
:%s/\r//g
або з
:1,$ s/^M//
Зауважте, що слід ввести ^ M, натиснувши ctrl-v, а потім ctrl-m.
^M
-s. Подолати це - тона натискань на клавіші, яка не для чого зроблена; Я б просто пішов на sed -i
, а потім `-e 's / \ r $ // g', щоб обмежити видалення на CR в EOL.
Ще раз рішення ... Тому що завжди є ще одне:
perl -i -pe 's/\r//' filename
Це приємно, оскільки він працює на своєму місці і працює в будь-якому ароматі unix / linux, з яким я працював.
Хтось ще рекомендує, dos2unix
і я також настійно рекомендую. Я просто надаю більше деталей.
Якщо встановлено, перейдіть до наступного кроку. Якщо це ще не встановлено, я рекомендую встановити його через yum
:
yum install dos2unix
Тоді ви можете використовувати його так:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Якщо ви використовуєте ОС (як 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
ім'я в командному рядку таким же чином, як і в інших прикладах.
Ось річ,
%0d
- символ повернення каретки. Щоб зробити його сумісним з Unix. Нам потрібно скористатися командою нижче.
dos2unix fileName.extension fileName.extension
Для 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"
Якщо ви використовуєте середовище X та маєте належний редактор (візуальний код студії), я б дотримувався рекомендації:
Код Visual Studio: Як показати закінчення рядків
Просто перейдіть до правого нижнього кута екрана, візуальний код студії покаже вам кодування файлу та закінчення конвенції рядка з подальшим файлом, просто за допомогою простого клацання ви можете переключити це навколо.
Просто використовуйте візуальний код як заміну для блокнота ++ у середовищі Linux, і ви готові працювати.
Notepad++
командою для Edit / EOL Conversion / Unix (LF)
в системі Windows, перш ніж скопіювати файл у вашу систему Linux.
\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
спеціальним чином, як це робить 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
%
Хоча це і старший пост, нещодавно я зіткнувся з такою ж проблемою. Оскільки у мене були всі файли для перейменування всередині / 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
Примітка. Цей приклад не дуже точний, хоч і близький до того, що я працював (тут згадую лише для того, щоб краще зрозуміти, що я робив)
Я створив цей скрипт оболонки, щоб видалити символ \ 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
ви можете просто зробити це:
$ echo $(cat input) > output
a * b
...