Come apparirebbe uno awk
script (presumibilmente un one-liner) per la rimozione di una distinta materiali ?
Specifica:
- stampa ogni riga dopo la prima (
NR > 1
) - per la prima riga: se inizia con
#FE #FF
o#FF #FE
, rimuovili e stampa il resto
Come apparirebbe uno awk
script (presumibilmente un one-liner) per la rimozione di una distinta materiali ?
Specifica:
NR > 1
)#FE #FF
o #FF #FE
, rimuovili e stampa il restoRisposte:
Prova questo:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
Nel primo record (riga), rimuovere i caratteri BOM. Stampa ogni record.
O leggermente più breve, utilizzando la consapevolezza che l'azione predefinita in awk è stampare il record:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1
è la condizione più breve che restituisce sempre true, quindi ogni record viene stampato.
Godere!
- ADDENDUM -
Le domande frequenti su Unicode Byte Order Mark (BOM) includono la seguente tabella che elenca i byte BOM esatti per ciascuna codifica:
Bytes | Encoding Form
--------------------------------------
00 00 FE FF | UTF-32, big-endian
FF FE 00 00 | UTF-32, little-endian
FE FF | UTF-16, big-endian
FF FE | UTF-16, little-endian
EF BB BF | UTF-8
Quindi, puoi vedere come \xef\xbb\xbf
corrisponde ai EF BB BF
UTF-8
byte BOM dalla tabella sopra.
awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' INFILE > OUTFILE
e assicurati che INFILE e OUTFILE siano diversi!
perl -i.orig -pe 's/^\x{FFFE}//' badfile
usassi, potresti fare affidamento sulle tue invariabili PERL_UNICODE e / o PERLIO per la codifica. PERL_UNICODE = SD funzionerebbe per UTF-8; per gli altri, avresti bisogno di PERLIO.
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1'
Utilizzando GNU sed
(su Linux o Cygwin):
# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt
Su FreeBSD:
sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt
Vantaggio dell'uso di GNU o FreeBSD sed
: il -i
parametro significa "in place" e aggiornerà i file senza bisogno di reindirizzamenti o strani trucchi.
Su Mac:
Questa awk
soluzione in un'altra risposta funziona , ma il sed
comando sopra non funziona. Almeno su Mac (Sierra) la sed
documentazione non menziona il supporto dell'escaping esadecimale ala \xef
.
Un trucco simile può essere ottenuto con qualsiasi programma collegandosi allo sponge
strumento da moreutils :
awk '…' INFILE | sponge INFILE
10.11.6
, questo non funziona, ma la risposta ufficiale stackoverflow.com/a/1068700/9636 funziona bene.
Non strano, ma più semplice:
tail -c +4 UTF8 > UTF8.nobom
Per verificare la distinta base:
hd -n 3 UTF8
Se BOM è presente vedrai: 00000000 ef bb bf ...
cat file1.utf8 file2.utf8 file3.utf3 > allfiles.utf8
sarà rotto. Non utilizzare mai una distinta base su UTF-8. Periodo.
hd
non è disponibile su OS X (a partire da 10.8.2), in modo da verificare la presenza di un UTF-8 BOM lì è possibile utilizzare il seguente: head -c 3 file | od -t x1
.
Oltre a convertire le terminazioni di riga CRLF in LF, dos2unix
rimuove anche le distinte materiali:
dos2unix *.txt
dos2unix
converte anche i file UTF-16 con una BOM (ma non i file UTF-16 senza BOM) in UTF-8 senza BOM:
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16be>bom-utf16be
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16le>bom-utf16le
$ printf '\ufeffä\n'>bom-utf8
$ printf 'ä\n'|iconv -f utf-8 -t utf-16be>utf16be
$ printf 'ä\n'|iconv -f utf-8 -t utf-16le>utf16le
$ printf 'ä\n'>utf8
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be feff00e4000a
bom-utf16le fffee4000a00
bom-utf8 efbbbfc3a40a
utf16be 00e4000a
utf16le e4000a00
utf8 c3a40a
$ dos2unix -q *
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be c3a40a
bom-utf16le c3a40a
bom-utf8 c3a40a
utf16be 00e4000a
utf16le e4000a00
utf8 c3a40a
So che la domanda era rivolta a unix / linux, ho pensato che varrebbe la pena menzionare una buona opzione per unix-challenge (su Windows, con un'interfaccia utente).
Mi sono imbattuto nello stesso problema su un progetto WordPress (BOM stava causando problemi con feed RSS e convalida della pagina) e ho dovuto esaminare tutti i file in un albero di directory abbastanza grande per trovare quello che era con BOM. Trovato un'applicazione chiamata Replace Pioneer e in essa:
Batch Runner -> Cerca (per trovare tutti i file nelle sottocartelle) -> Sostituisci modello -> Binario rimuovi BOM (c'è un modello di ricerca e sostituzione già pronto per questo).
Non era la soluzione più elegante e richiedeva l'installazione di un programma, il che è uno svantaggio. Ma una volta scoperto cosa mi stava succedendo, ha funzionato a meraviglia (e ho trovato 3 file su circa 2300 che erano con BOM).