Jaki jest najprostszy sposób na usunięcie wszystkich zwrotów karetki \r
z pliku w systemie Unix?
Jaki jest najprostszy sposób na usunięcie wszystkich zwrotów karetki \r
z pliku w systemie Unix?
Odpowiedzi:
Mam zamiar założyć chodziło Ci powrotu karetki ( CR, "\r"
, 0x0d
) przy końcach linii zamiast po prostu ślepo wewnątrz pliku (można je mieć w środku ciągów dla wszystkich wiem). Używając tego pliku testowego tylko CRna końcu pierwszego wiersza:
$ 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
jest to droga, jeśli jest zainstalowany w twoim systemie:
$ cat infile | dos2unix -U | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Jeśli z jakiegoś powodu dos2unix
nie jest dla ciebie dostępny, sed
zrobi to:
$ cat infile | sed 's/\r$//' | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Jeśli z jakiegoś powodu sed
nie jesteś dla ciebie dostępny, ed
zrób to w skomplikowany sposób:
$ 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
Jeśli nie masz żadnego z tych narzędzi zainstalowanych na swoim urządzeniu, masz większe problemy niż próba konwersji plików :-)
\r
działa tylko z GNU sed, w przeciwnym razie możesz to zrobić:sed `echo "s/\r//"`
sed
nie echo
rozpoznaj \r
na MacO. W tym przypadku printf "\r"
wydaje się, że działa.
sed "s/$(printf '\r')\$//"
$
tak: sed $'s@\r@@g' |od -c
(ale jeśli chcesz zamienić z \n
tobą musiałby uciec)
tr -d '\r' < infile > outfile
Zobacz tr (1)
tr
nie obsługuje \r
ucieczki, spróbuj, '\015'
a może dosłownie '^M'
(w wielu powłokach na wielu terminalach, ctrl-V ctrl-M wytworzy literalny znak ctrl-M).
outfile = infile
?
someProg <in >out && mv out in
.
Najprostszym sposobem na Linuksa jest, moim skromnym zdaniem,
sed -i 's/\r$//g' <filename>
Te silne cytaty wokół operatora podstawienia 's/\r//'
są niezbędne . Bez nich powłoka będzie interpretować \r
jako escape + r i zredukuje ją do zwykłego r
, i usunie wszystkie małe litery r
. Dlatego odpowiedź podana powyżej w 2009 roku przez Roba nie działa.
Dodanie /g
modyfikatora zapewnia \r
usunięcie nawet wielu , a nie tylko pierwszego.
Istnieje narzędzie o nazwie dos2unix, które istnieje w wielu systemach i można je łatwo zainstalować w większości.
sed -i s/\r// <filename>
lub coś takiego; zobacz man sed
lub bogactwo informacji dostępnych w Internecie dotyczących korzystania z sed
.
Jedna rzecz, na którą należy zwrócić uwagę, to dokładne znaczenie „powrotu karetki” powyżej; jeśli naprawdę masz na myśli pojedynczy znak kontrolny „powrót karetki”, to powyższy wzór jest poprawny. Jeśli masz na myśli, bardziej ogólnie, CRLF (powrót karetki i przesunięcie wiersza, czyli sposób, w jaki przesunięcia wiersza są wdrażane w systemie Windows), prawdopodobnie prawdopodobnie \r\n
zamiast tego chcesz zamienić . Nagie źródła linii (nowa linia) w systemie Linux / Unix to \n
.
Jeśli jesteś użytkownikiem Vi, możesz otworzyć plik i usunąć znak powrotu karetki za pomocą:
:%s/\r//g
lub z
:1,$ s/^M//
Zauważ, że powinieneś wpisać ^ M, naciskając ctrl-v, a następnie ctrl-m.
^M
-s. Poradzenie sobie z tym to mnóstwo naciśnięć klawiszy, co nie jest stworzone dla vima;). Po prostu wybrałbym sed -i
, a następnie `-e 's / \ r $ // g', aby ograniczyć usuwanie do CR w EOL.
Jeszcze raz rozwiązanie ... Ponieważ zawsze jest jeszcze jedno:
perl -i -pe 's/\r//' filename
Jest fajny, ponieważ jest na miejscu i działa w każdym smaku unix / linux, z którym pracowałem.
Ktoś inny poleca dos2unix
i ja też zdecydowanie polecam. Podaję tylko więcej szczegółów.
Jeśli jest zainstalowany, przejdź do następnego kroku. Jeśli jeszcze nie został zainstalowany, zaleciłbym jego instalację poprzez yum
:
yum install dos2unix
Następnie możesz użyć go w następujący sposób:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Jeśli używasz systemu operacyjnego (takiego jak OS X), który nie ma dos2unix
polecenia, ale ma interpreter języka Python (wersja 2.5+), to polecenie jest równoważne dos2unix
poleceniu:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
To obsługuje zarówno nazwane pliki w wierszu poleceń, jak i potoki i przekierowania, podobnie jak dos2unix
. Jeśli dodasz ten wiersz do pliku ~ / .bashrc (lub równoważnego pliku profilu dla innych powłok):
alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""
... przy następnym logowaniu (lub uruchomieniu source ~/.bashrc
w bieżącej sesji) będziesz mógł użyć dos2unix
nazwy w wierszu poleceń w taki sam sposób, jak w innych przykładach.
Oto rzecz
%0d
jest znakiem powrotu karetki. Aby był kompatybilny z Uniksem. Musimy użyć poniższego polecenia.
dos2unix fileName.extension fileName.extension
W systemie UNIX ... zauważyłem, że dos2unix usunął nagłówki Unicode z mojego pliku UTF-8. Pod git bash (Windows) następujący skrypt wydaje się działać dobrze. Używa sed. Zauważ, że usuwa tylko znaki powrotu karetki na końcach linii i zachowuje nagłówki Unicode.
#!/bin/bash
inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
Jeśli używasz środowiska X i masz odpowiedni edytor (kod Visual Studio), postąpiłbym zgodnie z zaleceniem:
Visual Studio Code: Jak wyświetlać zakończenia linii
Po prostu przejdź do prawego dolnego rogu ekranu, kod Visual Studio pokaże zarówno kodowanie pliku, jak i konwencję końca linii, a następnie plik - jednym kliknięciem możesz go przełączać.
Po prostu użyj kodu wizualnego jako zamiennika notatnika ++ w środowisku Linux i możesz zacząć.
Notepad++
polecenia Edit / EOL Conversion / Unix (LF)
w systemie Windows przed skopiowaniem pliku do systemu Linux.
\r
w dowolnym systemie UNIX®:Większość istniejących rozwiązań w tym pytaniu jest specyficznych dla GNU i nie działałaby na OS X lub BSD; Poniższe rozwiązania powinny działać na wielu innych systemach UNIX, aw każdym powłoki, z tcsh
celu sh
, ale wciąż działa nawet na GNU / Linux, too.
Testowane na OS X, OpenBSD i NetBSD w tcsh
oraz na Debian GNU / Linux w bash
.
sed
:W tcsh
systemie OS X sed
można używać następującego fragmentu kodu printf
, ponieważ ani sed
nie echo
obsługuje się go \r
w specjalny sposób, jak GNU:
sed `printf 's/\r$//g'` input > output
tr
:Inną opcją jest tr
:
tr -d '\r' < input > output
sed
i tr
:Wygląda na to, że tr
zachowuje brak końcowej nowej linii z pliku wejściowego, podczas gdy sed
w OS X i NetBSD (ale nie w OpenBSD lub GNU / Linux) wstawia końcową nową linię na samym końcu pliku, nawet jeśli w danych wejściowych brakuje jakiejkolwiek na końcu \r
lub \n
na samym końcu pliku.
Oto kilka przykładowych testów, które można wykorzystać, aby upewnić się, że działa to w twoim systemie, używając printf
i hexdump -C
; alternatywnie, od -c
można również użyć, jeśli brakuje twojego systemu 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
%
Chociaż jest to starszy post, ostatnio natknąłem się na ten sam problem. Ponieważ miałem wszystkie pliki do zmiany nazwy w / tmp / blah_dir /, ponieważ każdy plik w tym katalogu miał znak końcowy „/ r” (pokazujący „?” Na końcu pliku), więc zrobienie tego w sposób skryptowy było tylko tym, co mogłem wymyślić.
Chciałem zapisać końcowy plik o tej samej nazwie (bez kończenia żadnego znaku). W przypadku seda problemem była wyjściowa nazwa pliku, której potrzebowałem, aby wspomnieć o czymś innym (czego nie chciałem).
Wypróbowałem inne opcje, jak tutaj sugerowane (nie uważane za dos2unix z powodu pewnych ograniczeń), ale nie działało.
W końcu spróbowałem z „awk”, który działał tam, gdzie użyłem „\ r” jako separatora i wziąłem pierwszą część :
sztuczka polega na:
echo ${filename}|awk -F"\r" '{print $1}'
Poniżej fragmentu skryptu, którego użyłem (gdzie wszystkie pliki miały „\ r” jako znak końcowy na ścieżce / tmp / blah_dir /), aby naprawić mój problem:
cd /tmp/blah_dir/
for i in `ls`
do
mv $i $(echo $i | awk -F"\r" '{print $1}')
done
Uwaga: ten przykład nie jest bardzo dokładny, chociaż jest bliski temu, co pracowałem (wspomnienie tutaj tylko po to, aby lepiej zrozumieć, co zrobiłem)
Zrobiłem ten skrypt powłoki, aby usunąć znak \ r. Działa w solaris i red-hat:
#!/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
możesz po prostu to zrobić:
$ echo $(cat input) > output
a * b
...