Come posso programmare a livello di codice (cioè, non usando vi
) convertire le newline DOS / Windows in Unix?
I comandi dos2unix
e unix2dos
non sono disponibili su alcuni sistemi. Come posso emularli con comandi come sed
/ awk
/ tr
?
Puoi usare tr
per convertire da DOS a Unix; tuttavia, puoi farlo in sicurezza solo se CR appare nel tuo file solo come primo byte di una coppia di byte CRLF. Questo di solito è il caso. Quindi usi:
tr -d '\015' UNIX-file
Si noti che il nome DOS-file
è diverso dal nome UNIX-file
; se si tenta di utilizzare lo stesso nome due volte, si finirà con nessun dato nel file.
Non puoi farlo al contrario (con lo standard ‘tr’).
Se sai come inserire il ritorno a capo in uno script ( control-V , control-M per entrare in control-M), allora:
sed 's/^M$//' # DOS to Unix sed 's/$/^M/' # Unix to DOS
dove ‘^ M’ è il carattere di controllo-M. È inoltre ansible utilizzare il meccanismo di bash
ANSI-C bash
per specificare il ritorno a capo:
sed $'s/\r$//' # DOS to Unix sed $'s/$/\r/' # Unix to DOS
Tuttavia, se devi farlo molto spesso (più di una volta, più o meno, in modo approssimativo), è molto più sensato installare i programmi di conversione (ad esempio dos2unix
e unix2dos
, o forse dtou
e utod
) e usarli.
tr -d "\r" < file
dai un'occhiata qui per esempi usando sed
:
# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format. sed 's/.$//' # assumes that all lines end with CR/LF sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M sed 's/\x0D$//' # works on ssed, gsed 3.02.80 or higher # IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format. sed "s/$/`echo -e \\\r`/" # command line under ksh sed 's/$'"/`echo \\\r`/" # command line under bash sed "s/$/`echo \\\r`/" # command line under zsh sed 's/$/\r/' # gsed 3.02.80 or higher
Usa sed -i
per la conversione sul posto, ad esempio il file di sed -i 's/..../' file
.
Fare questo con POSIX è complicato:
POSIX Sed non supporta \r
o \15
. Anche se così fosse, l’opzione sul posto -i
non è POSIX
POSIX Awk supporta \r
e \15
, tuttavia l’opzione -i inplace
non è POSIX
d2u e dos2unix non sono utilità POSIX , ma ex è
POSIX ex non supporta \r
, \15
, \n
o \12
Per rimuovere i ritorni a capo:
ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file
Per aggiungere ritorni a capo:
ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file
Questo problema può essere risolto con strumenti standard, ma ci sono un numero sufficiente di trappole per gli incauti che consiglio di installare il comando flip
, che è stato scritto più di 20 anni fa da Rahul Dhesi, l’autore dello zoo
. Fa un ottimo lavoro nella conversione dei formati di file mentre, ad esempio, evita la distruzione involontaria dei file binari, il che è un po ‘troppo facile se si corre semplicemente a modificare ogni CRLF che si vede …
Usando AWK puoi fare:
awk '{ sub("\r$", ""); print }' dos.txt > unix.txt
Usando Perl puoi fare:
perl -pe 's/\r$//' < dos.txt > unix.txt
Le soluzioni pubblicate finora trattano solo parte del problema, convertendo il CRLF di DOS / Windows in LF di Unix; la parte che mancano è che DOS usa CRLF come separatore di riga, mentre Unix usa LF come terminatore di riga. La differenza è che un file DOS (di solito) non avrà nulla dopo l’ultima riga nel file, mentre Unix lo farà. Per eseguire correttamente la conversione, è necessario aggiungere l’ultimo LF (a meno che il file non abbia una lunghezza pari a zero, ovvero non ci siano linee in esso). Il mio incantesimo preferito per questo (con una piccola logica aggiunta per gestire i file separati da CR in stile Mac, e non i file molest che sono già in formato Unix) è un po ‘perlativo:
perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt
Notare che questo invia la versione Unixified del file allo stdout. Se vuoi sostituire il file con una versione Unixified, aggiungi il flag -i
di perl.
Se non hai accesso a dos2unix , ma puoi leggere questa pagina, puoi copiare / incollare dos2unix.py da qui.
#!/usr/bin/env python """\ convert dos linefeeds (crlf) to unix (lf) usage: dos2unix.py
Cross-postato da superuser .
Una soluzione awk ancora più semplice con un programma:
awk -v ORS='\r\n' '1' unix.txt > dos.txt
Tecnicamente ‘1’ è il tuo programma, b / c awk ne richiede uno quando viene data l’opzione.
AGGIORNAMENTO : Dopo aver rivisitato questa pagina per la prima volta dopo molto tempo, mi sono reso conto che nessuno ha ancora pubblicato una soluzione interna, quindi eccone una:
while IFS= read -r line; do printf '%s\n' "${line%$'\r'}"; done < dos.txt > unix.txt
Super duper facile con PCRE;
Come script, o sostituisci [email protected]
con i tuoi file.
#!/usr/bin/env bash perl -pi -e 's/\r\n/\n/g' -- [email protected]
Questo sovrascriverà i tuoi file sul posto!
Consiglio di farlo solo con un backup (controllo della versione o altro)
interessante nel mio git-bash su windows sed ""
ha già fatto il trucco:
$ echo -e "abc\r" >tst.txt $ file tst.txt tst.txt: ASCII text, with CRLF line terminators $ sed -i "" tst.txt $ file tst.txt tst.txt: ASCII text
La mia ipotesi è che sed li ignori leggendo le righe dall’input e scriva sempre unix line endings in output.
Questo ha funzionato per me
tr "\r" "\n" < sampledata.csv > sampledata2.csv
Per convertire un file in atto fai
dos2unix
Per produrre il testo convertito in un file diverso, fare
dos2unix -n
È già installato su Ubuntu ed è disponibile su homebrew
brew install dos2unix
So che la domanda richiede esplicitamente alternative a questa utility, ma questo è il primo risultato di ricerca su google per “convertire dos in unix terminazioni di riga”.
TIMTOWTDI!
perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof' PCfile.txt
Basato su @GordonDavisson
Bisogna considerare la possibilità di [noeol]
…
Per Mac osx se hai installato homebrew [ http://brew.sh/%5D%5B1%5D
brew install dos2unix for csv in *.csv; do dos2unix -c mac ${csv}; done;
Assicurati di aver fatto delle copie dei file, poiché questo comando modificherà i file sul posto. L’opzione -c mac rende lo switch compatibile con osx.
Puoi usare awk. Imposta il separatore di record ( RS
) su un’espressione regolare che corrisponda a tutti i possibili caratteri o caratteri di nuova riga. E imposta il separatore dei record di uscita ( ORS
) sul carattere di nuova riga di tipo unix.
awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt
Come estensione della soluzione Unix a DOS di Jonathan Leffler, per convertire in sicurezza in DOS quando non si è sicuri delle terminazioni di riga del file corrente:
sed '/^M$/! s/$/^M/'
Questo controlla che la riga non finisca già in CRLF prima di convertirsi in CRLF.
Dovevo solo ponderare la stessa domanda (sul lato Windows, ma ugualmente applicabile a Linux.) Sorprendentemente nessuno ha menzionato un modo molto automatico di fare CRLF <-> Conversione LF per file di testo usando la vecchia e buona opzione zip -ll
(Info- CERNIERA LAMPO):
zip -ll textfiles-lf.zip files-with-crlf-eol.* unzip textfiles-lf.zip
NOTA: questo creerebbe un file zip preservando i nomi dei file originali ma convertendo le terminazioni di linea in LF. Quindi unzip
estrarre i file come zip, cioè con i loro nomi originali (ma con terminazioni LF), chiedendo così di sovrascrivere i file originali locali, se presenti.
Estratto pertinente dallo zip --help
:
zip --help ... -l convert LF to CR LF (-ll CR LF to LF)
Su Linux è facile convertire ^ M (ctrl-M) in * nix newlines (^ J) con sed.
Sarà qualcosa di simile sulla CLI, ci sarà effettivamente un’interruzione di riga nel testo. Tuttavia, il \ passa quello ^ J insieme a sed:
sed 's/^M/\ /g' < ffmpeg.log > new.log
Puoi ottenere ciò usando ^ V (ctrl-V), ^ M (ctrl-M) e \ (backslash) mentre scrivi:
sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log
Puoi usare vim a livello di codice con l’opzione -c {comando}:
Da Dos a Unix:
vim file.txt -c "set ff=unix" -c ":wq"
Unix da dosare:
vim file.txt -c "set ff=dos" -c ":wq"
Ho provato sed ‘s / ^ M $ //’ file.txt su OSX così come molti altri metodi ( http://www.thingy-ma-jig.co.uk/blog/25-11-2010/fixing- dos-line-endings o http://hintsforums.macworld.com/archive/index.php/t-125.html ). Nessuno ha funzionato, il file è rimasto invariato (era necessario Ctrl-v Enter per riprodurre ^ M). Alla fine ho usato TextWrangler. Non è una riga di comando strettamente ma funziona e non si lamenta.
Ci sono un sacco di risposte awk / sed / etc così come un supplemento (poiché questo è uno dei risultati di ricerca principali per questo problema):
Non puoi avere dos2unix ma hai iconv ?
iconv -f UTF-16LE -t UTF-8 [filename.txt] -f from format type -t to format type
O tutti i file in una directory:
find . -name "*.sql" -exec iconv -f UTF-16LE -t UTF-8 {} -o ./{} \;
Questo esegue lo stesso comando, su tutti i file .sql nella cartella corrente. -o è la directory di output in modo che tu possa averlo a sostituire i file correnti, o, per ragioni di sicurezza / backup, in uscita in una directory separata.