Usuń powrót karetki w Uniksie


Odpowiedzi:


261

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 dos2unixnie jest dla ciebie dostępny, sedzrobi 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 sednie jesteś dla ciebie dostępny, edzró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 :-)


13
\rdziała tylko z GNU sed, w przeciwnym razie możesz to zrobić:sed `echo "s/\r//"`
lapo

15
Ani sednie echorozpoznaj \rna MacO. W tym przypadku printf "\r"wydaje się, że działa.
Steve Powell,

30
Aby rozwinąć komentarz na @ steve: Na komputerze Mac użyj następujących sed "s/$(printf '\r')\$//"
poleceń

7
Do wydawania poprawek na mac można również poprzedzić apostrofu sed ciąg ze $tak: sed $'s@\r@@g' |od -c (ale jeśli chcesz zamienić z \ntobą musiałby uciec)
nhed

1
Nie jestem w 100% pewien, ale w przypadku OS X używanie CTRL-V + CTRL-Mzamiast \rwyglądu wygląda na to, że może działać.

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

Zobacz tr (1)


4
Nie wspaniale: 1. nie działa w miejscu, 2. może również zastąpić w EOL (co może, ale nie musi być to, czego chcesz ...).
Tomasz Gandor

10
1. Większość uniksowych narzędzi działa w ten sposób i zazwyczaj jest to najbezpieczniejszy sposób na załatwienie różnych spraw, ponieważ jeśli coś spieprzysz, nadal będziesz mieć oryginał. 2. Jak wspomniano, chodzi o usunięcie zwrotów karetki, a nie przekształcanie zakończeń linii. Ale istnieje wiele innych odpowiedzi, które mogą ci lepiej służyć.
Henrik Gustafsson,

1
Jeśli twój trnie obsługuje \rucieczki, 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).
tripleee

Jak więc to zmienić, kiedy chcesz outfile = infile?
Christopher

3
@donlan, późną odpowiedź ale zazwyczaj używać coś takiego: someProg <in >out && mv out in.
paxdiablo,

38

Stara szkoła:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

32

Najprostszym sposobem na Linuksa jest, moim skromnym zdaniem,

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

Te silne cytaty wokół operatora podstawienia 's/\r//'niezbędne . Bez nich powłoka będzie interpretować \rjako 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 /gmodyfikatora zapewnia \rusunięcie nawet wielu , a nie tylko pierwszego.



7

sed -i s/\r// <filename>lub coś takiego; zobacz man sedlub 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\nzamiast tego chcesz zamienić . Nagie źródła linii (nowa linia) w systemie Linux / Unix to \n.


Próbuję użyć -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt, który nie działa. „tygrys” „Lew”.
Suvasis,

czy mamy to na myśli, że masz komputer Mac? Zauważyłem, że Darwin sed domyślnie ma inne polecenia i zestawy funkcji niż większość wersji Linuksa ...
jsh

4
FYI, s/\r//wydaje się , że nie usuwa zwrotów karetki w OS X, wydaje się, że rzamiast tego dosłownie usuwa znaki. Nie jestem pewien, dlaczego tak jest. Może ma to coś wspólnego ze sposobem cytowania ciągu? Jako obejście wydaje się , że używanie CTRL-V + CTRL-Mzamiast zamiast \rdziała.

6

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.


2
Niezbyt dobrze: jeśli plik ma CR w każdej linii (tzn. Jest poprawnym plikiem DOS), vim załaduje go z filetype = dos, i wcale nie pokaże ^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.
Tomasz Gandor

6

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.


3

Ktoś inny poleca dos2unixi 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

2

Jeśli używasz systemu operacyjnego (takiego jak OS X), który nie ma dos2unixpolecenia, ale ma interpreter języka Python (wersja 2.5+), to polecenie jest równoważne dos2unixpoleceniu:

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 ~/.bashrcw bieżącej sesji) będziesz mógł użyć dos2unixnazwy w wierszu poleceń w taki sam sposób, jak w innych przykładach.


2

Oto rzecz

%0djest znakiem powrotu karetki. Aby był kompatybilny z Uniksem. Musimy użyć poniższego polecenia.

dos2unix fileName.extension fileName.extension



1

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"

1

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ąć.


Lub użyj Notepad++polecenia Edit / EOL Conversion / Unix (LF)w systemie Windows przed skopiowaniem pliku do systemu Linux.
Jesse Chisholm,

1

Usuwanie \rw 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 tcshcelu sh, ale wciąż działa nawet na GNU / Linux, too.

Testowane na OS X, OpenBSD i NetBSD w tcshoraz na Debian GNU / Linux w bash.


Z sed:

W tcshsystemie OS X sedmożna używać następującego fragmentu kodu printf, ponieważ ani sednie echoobsługuje się go \rw specjalny sposób, jak GNU:

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

Z tr:

Inną opcją jest tr:

tr -d '\r' < input > output

Różnica między sedi tr:

Wygląda na to, że trzachowuje brak końcowej nowej linii z pliku wejściowego, podczas gdy sedw 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 \rlub \nna samym końcu pliku.


Testowanie:

Oto kilka przykładowych testów, które można wykorzystać, aby upewnić się, że działa to w twoim systemie, używając printfi hexdump -C; alternatywnie, od -cmoż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
% 

0

Użyłem do tego Pythona, oto mój kod;

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

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)


0

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

-1

możesz po prostu to zrobić:

$ echo $(cat input) > output

Nie wiem, dlaczego ktoś dał „-1”. To jest doskonale dobra odpowiedź (i jedyna, która działała dla mnie).
FractalSpace

1
Przepraszam, to byłam ja. Poczekaj, patrz, to naprawdę nie działa dla '\ r'!
Viacheslav Rodionov,

1
@FractalSpace To okropny pomysł! Całkowicie niszczy wszystkie odstępy w pliku i pozostawia całą zawartość pliku do interpretacji przez powłokę. Wypróbuj z plikiem zawierającym jedną linię a * b...
Tom Fenech
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.