Qual è il modo più semplice per rimuovere tutti i ritorni a capo \r
da un file in Unix?
Qual è il modo più semplice per rimuovere tutti i ritorni a capo \r
da un file in Unix?
Risposte:
Ho intenzione di assumere che si ritorni a capo medi ( CR, "\r"
, 0x0d
) alle estremità delle linee piuttosto che solo alla cieca all'interno di un file (potrebbe essere li nel mezzo di stringhe per quanto ne so). Utilizzo di questo file di test con CRa 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 dos2unix
non è disponibile per te, sed
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 sed
non è disponibile per te, ed
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 nessuno di quegli strumenti installati sulla tua scatola, hai problemi più grandi rispetto al tentativo di convertire i file :-)
\r
funziona solo con GNU sed, altrimenti puoi farlo:sed `echo "s/\r//"`
sed
né echo
riconoscere \r
su MacOS. In questo caso printf "\r"
sembra funzionare solo.
sed "s/$(printf '\r')\$//"
$
modo: sed $'s@\r@@g' |od -c
(ma se dovessi sostituirlo con \n
te dovresti fuggire)
tr -d '\r' < infile > outfile
Vedi tr (1)
tr
non supporta la \r
fuga, prova '\015'
o forse un valore letterale '^M'
(in molte shell su molti terminali, ctrl-V ctrl-M produrrà un carattere letterale ctrl-M).
outfile = infile
?
someProg <in >out && mv out in
.
Il modo più semplice su Linux è, secondo la mia modesta opinione,
sed -i 's/\r$//g' <filename>
Le virgolette attorno all'operatore di sostituzione 's/\r//'
sono essenziali . Senza di essi, la shell interpreterà \r
come escape + r, la ridurrà in piano r
e rimuoverà tutte le lettere minuscole r
. Ecco perché la risposta data sopra nel 2009 da Rob non funziona.
E l'aggiunta del /g
modificatore assicura che anche multipli\r
verranno rimossi , e non solo il primo.
C'è un'utilità chiamata dos2unix che esiste su molti sistemi e può essere facilmente installata sulla maggior parte.
sed -i s/\r// <filename>
o somesuch; vedere man sed
o la ricchezza di informazioni disponibili sul web relative all'uso di sed
.
Una cosa da sottolineare è il significato preciso di "ritorno a capo" di cui sopra; se intendi veramente il singolo carattere di controllo "ritorno a capo", il modello sopra è corretto. Se intendevi, più in generale, CRLF (ritorno a capo e un avanzamento riga, ovvero come vengono implementati gli avanzamenti riga in Windows), probabilmente vorrai \r\n
invece sostituire . I feed di linea nuda (newline) in Linux / Unix sono \n
.
s/\r//
non sembra rimuovere i ritorni a capo su OS X, sembra r
invece rimuovere caratteri letterali . Non sono sicuro del perché. Forse ha qualcosa a che fare con il modo in cui viene citata la stringa? Come soluzione alternativa, l'utilizzo CTRL-V + CTRL-M
al posto di \r
sembra funzionare.
Se sei un utente Vi, puoi aprire il file e rimuovere il ritorno a capo con:
:%s/\r//g
o con
:1,$ s/^M//
Si noti che è necessario digitare ^ M premendo ctrl-v e quindi ctrl-m.
^M
-s. Aggirare questo è una tonnellata di tasti, che non è ciò per cui è fatto Vim;). Vorrei solo provare sed -i
, e quindi `-e 's / \ r $ // g' per limitare la rimozione ai CR presso EOL.
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 lo 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 yum
come:
yum install dos2unix
Quindi puoi usarlo come:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Se stai usando un sistema operativo (come OS X) che non ha il dos2unix
comando ma ha un interprete Python (versione 2.5+), questo comando è equivalente al dos2unix
comando:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
Questo gestisce sia i file con nome sulla riga di comando sia i pipe e i reindirizzamenti, proprio come dos2unix
. 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 source ~/.bashrc
nella sessione corrente) sarai in grado di usare il dos2unix
nome sulla riga di comando nello stesso modo degli altri esempi.
Ecco la cosa,
%0d
è il carattere di ritorno a capo. Per renderlo compatibile con Unix. Dobbiamo usare il comando seguente.
dos2unix fileName.extension fileName.extension
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 alle estremità delle linee 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, con un semplice clic puoi cambiarlo.
Usa semplicemente il codice visivo come sostituto di notepad ++ in un ambiente Linux e sei pronto per partire.
Notepad++
il comando 's Edit / EOL Conversion / Unix (LF)
sul tuo sistema Windows prima di copiare il file sul tuo sistema Linux.
\r
su qualsiasi sistema UNIX®:La maggior parte delle soluzioni esistenti in questa domanda sono specifiche di GNU e non funzionerebbero su OS X o BSD; le soluzioni sottostanti dovrebbero funzionare su molti più sistemi UNIX, e in qualsiasi shell, da tcsh
a sh
, eppure funzionare anche su GNU / Linux.
Testato su OS X, OpenBSD e NetBSD in tcsh
, e su Debian GNU / Linux in bash
.
sed
:In tcsh
su un OS X, il seguente sed
frammento di codice potrebbe essere utilizzato insieme printf
, in quanto né sed
nè echo
manico \r
in modo speciale come la GNU fa:
sed `printf 's/\r$//g'` input > output
tr
:Un'altra opzione è tr
:
tr -d '\r' < input > output
sed
e tr
:Sembrerebbe che tr
preservi la mancanza di una nuova riga finale dal file di input, mentre sed
su OS X e NetBSD (ma non su OpenBSD o GNU / Linux) inserisce una nuova riga finale alla fine del file anche se nell'input manca qualche finale \r
o \n
alla fine del file.
Ecco alcuni test di esempio che potrebbero essere utilizzati per garantire che funzioni sul tuo sistema, usando printf
e hexdump -C
; in alternativa, od -c
potrebbe essere utilizzato anche in mancanza del sistema 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
%
Anche se è un post più vecchio, recentemente ho riscontrato lo stesso problema. Dato che avevo tutti i file da rinominare all'interno di / tmp / blah_dir / dato che ogni file in questa directory aveva il carattere finale "/ r" (che mostra "?" Alla fine del file), quindi fare lo script in modo che solo io potevo pensare.
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 ha funzionato dove ho usato "\ r" come delimitatore e ho preso la prima parte :
il trucco è:
echo ${filename}|awk -F"\r" '{print $1}'
Sotto lo snippet di script ho usato (dove avevo tutti i file con "\ r" come carattere finale nel percorso / 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)
Ho creato questo shell-script per rimuovere il carattere. Funziona in Solaris e 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
puoi semplicemente farlo:
$ echo $(cat input) > output
a * b
...