Domanda

Qual è il modo più semplice per rimuovere tutti i ritorni a capo \r da un file in Unix?

È stato utile?

Soluzione

Suppongo che intendi i ritorni a capo ( CR , "\r", 0x0d) alle estremità delle linee anziché semplicemente alla cieca all'interno di un file (potresti averli nel mezzo di stringhe per tutto quello che so). Utilizzo di questo file di test con un CR solo alla fine della prima riga:

$ 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 è la strada da percorrere se è installato sul tuo sistema:

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

Se per qualche motivo sed non è disponibile per te, ed lo farà:

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

Se per qualche motivo <=> non è disponibile per te, <=> lo farà in modo complicato:

$ 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

Se non hai alcun di quegli strumenti installati sulla tua scatola, hai problemi più grandi rispetto al tentativo di convertire i file :-)

Altri suggerimenti

tr -d '\r' < infile > outfile

Vedi tr (1)

Vecchia scuola:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

Esiste un'utilità chiamata dos2unix che esiste su molti sistemi e può essere facilmente installata sulla maggior parte.

Il modo più semplice su Linux è, a mio modesto parere,

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

Le virgolette forti intorno all'operatore di sostituzione 's/\r//' sono essenziali . Senza di essi la shell interpreterà \r come escape + r e la ridurrà in un semplice r e rimuoverà tutte le lettere minuscole /g. Ecco perché la risposta di cui sopra nel 2009 da Rob non funziona.

E l'aggiunta del modificatore <=> assicura che anche più <=> vengano rimossi e non solo il primo.

sed -i s/\r// <filename> o somesuch; vedi man sed o la ricchezza di informazioni disponibili sul web riguardo all'uso di sed.

Una cosa da sottolineare è il significato preciso di " ritorno a capo " nel sopra; se intendi veramente il singolo carattere di controllo " ritorno a capo " ;, allora il modello sopra è corretto. Se intendevi, più in generale, CRLF (ritorno a capo e un avanzamento riga, ovvero il modo in cui gli avanzamenti riga sono implementati in Windows), probabilmente vorrai invece sostituire \r\n. I feed di linea nuda (newline) in Linux / Unix sono \n.

Se sei un utente Vi, puoi aprire il file e rimuovere il ritorno a capo con:

:%s/\r//g

o con

:1,$ s/^M//

Nota che dovresti digitare ^ M premendo ctrl-v e poi ctrl-m.

Ancora una volta una soluzione ... Perché ce n'è sempre un'altra:

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

È bello perché è a posto e funziona in tutti i gusti di unix / linux con cui ho lavorato.

Qualcun altro consiglia dos2unix e lo consiglio vivamente anche io. Sto solo fornendo maggiori dettagli.

Se installato, vai al passaggio successivo. Se non è già installato, consiglierei di installarlo tramite yum come:

yum install dos2unix

Quindi puoi usarlo come:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt

Ecco il punto

%0d è il carattere di ritorno a capo. Per renderlo compatibile con Unix. Dobbiamo usare il comando seguente.

dos2unix fileName.extension fileName.extension

prova questo per convertire il file dos in file unix:

  

file fromdos

Se stai usando un sistema operativo (come OS X) che non ha il comando dos2unix ma ha un interprete Python (versione 2.5+), questo comando è equivalente al comando source ~/.bashrc:

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

Gestisce sia i file con nome sulla riga di comando sia i pipe e i reindirizzamenti, proprio come <=>. Se aggiungi questa linea al tuo file ~ / .bashrc (o file di profilo equivalente per altre shell):

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

... la prossima volta che accedi (o esegui <=> nella sessione corrente) sarai in grado di usare il <=> nome sulla riga di comando allo stesso modo degli altri esempi.

Per UNIX ... ho notato che dos2unix ha rimosso le intestazioni Unicode dal mio file UTF-8. Sotto git bash (Windows), il seguente script sembra funzionare bene. Usa sed. Nota rimuove solo i ritorni a capo alla fine delle righe e conserva le intestazioni Unicode.

#!/bin/bash

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

Se si esegue un ambiente X e si dispone di un editor appropriato (codice Visual Studio), seguirei la raccomandazione:

Codice di Visual Studio: come mostrare le terminazioni di riga

Basta andare nell'angolo in basso a destra dello schermo, il codice di Visual Studio ti mostrerà sia la codifica del file che la convenzione di fine riga seguita dal file, e con un semplice clic puoi cambiarlo.

Usa semplicemente il codice visivo come sostituto di notepad ++ in un ambiente Linux e sei pronto per andare.

Ho usato Python per questo, qui il mio codice;

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)

Anche se è un post più vecchio, recentemente ho riscontrato lo stesso problema. Dato che avevo tutti i file da rinominare in / tmp / blah_dir / dato che ogni file in questa directory aveva & Quot; / r & Quot; carattere finale (che mostra "? " alla fine del file), quindi farlo in modo script era solo quello che mi veniva in mente.

Volevo salvare il file finale con lo stesso nome (senza trascinare alcun carattere). Con sed, il problema era il nome del file di output di cui avevo bisogno per menzionare qualcos'altro (che non volevo).

Ho provato altre opzioni come suggerito qui (non considerato dos2unix a causa di alcune limitazioni) ma non ha funzionato.

Ho provato con " awk " che infine ha funzionato dove ho usato " \ r " come delimitatore e preso la prima parte :

il trucco è:

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

Sotto lo snippet di script che ho usato (dove avevo tutti i file aveva " \ r " come carattere finale in path / tmp / blah_dir /) per risolvere il mio problema:

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

Nota: questo esempio non è molto esatto anche se vicino a quello che ho lavorato (menzionando qui solo per dare un'idea migliore di ciò che ho fatto)

puoi semplicemente farlo:

$ echo $(cat input) > output
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top