Verwenden Sie awk, um die Byte-Order-Markierung zu entfernen

Wie würde ein awk Skript (vermutlich ein Einzeiler) zum Entfernen einer Stückliste aussehen?

Spezifikation:

  • drucke jede Zeile nach der ersten ( NR > 1 )
  • Für die erste Zeile: Wenn es mit #FE #FF oder #FF #FE , entferne diese und #FF #FE den Rest aus

Solutions Collecting From Web of "Verwenden Sie awk, um die Byte-Order-Markierung zu entfernen"

Versuche dies:

 awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE 

Entfernen Sie die Stücklistenzeichen auf dem ersten Datensatz (Zeile). Drucke jeden Datensatz.

Oder etwas kürzer, mit dem Wissen, dass die Standardaktion in awk das Drucken des Datensatzes ist:

 awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE 

1 ist die kürzeste Bedingung, die immer als wahr ausgewertet wird, sodass jeder Datensatz gedruckt wird.

Genießen!

– NACHTRAG –

Unicode Byte Order Mark (BOM) FAQ enthält die folgende Tabelle mit den genauen Stücklisten-Bytes für jede Codierung:

 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 

So können Sie sehen, wie \xef\xbb\xbf EF BB BF UTF-8 BOM-Bytes aus der obigen Tabelle entspricht.

Mit GNU sed (auf Linux oder Cygwin):

 # Removing BOM from all text files in current directory: sed -i '1 s/^\xef\xbb\xbf//' *.txt 

Auf FreeBSD:

 sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt 

Vorteil der Verwendung von GNU oder FreeBSD sed : Der Parameter -i bedeutet “an Ort und Stelle” und aktualisiert die Dateien ohne Umleitungen oder seltsame Tricks.

Auf dem Mac:

Diese awk Lösung in einer anderen Antwort funktioniert , aber der obige sed Befehl funktioniert nicht. Zumindest auf Mac (Sierra) sed Dokumentation erwähnt nicht unterstützen hexadezimale \xef .

Ein ähnlicher Trick kann mit jedem Programm erreicht werden, indem man das sponge Werkzeug von moreutils anpasst :

 awk '…' INFILE | sponge INFILE 

Nicht awk, aber einfacher:

 tail -c +4 UTF8 > UTF8.nobom 

Um nach Stückliste zu suchen:

 hd -n 3 UTF8 

Wenn BOM vorhanden ist, sehen Sie: 00000000 ef bb bf ...

Neben der Konvertierung von CRLF-Zeilenendungen in LF entfernt dos2unix auch Stücklisten:

 dos2unix *.txt 

dos2unix konvertiert auch UTF-16-Dateien mit einer Stückliste (aber keine UTF-16-Dateien ohne eine Stückliste) in UTF-8 ohne eine Stückliste:

 $ 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 

Ich weiß, dass die Frage auf unix / linux gerichtet war, dachte, es wäre eine gute Option für die Unix-herausgefordert erwähnen (auf Windows, mit einer UI).
Ich stieß auf dasselbe Problem in einem WordPress-Projekt (BOM verursachte Probleme mit dem RSS-Feed und der Seitenüberprüfung) und ich musste in alle Dateien in einem ziemlich großen Verzeichnisbaum schauen, um den mit BOM zu finden. Gefunden eine Anwendung namens Replace Pioneer und darin:

Batch Runner -> Search (um alle Dateien in den Unterordnern zu finden) -> Template ersetzen -> Binary BOM entfernen (dafür gibt es eine vorgefertigte Such- und Ersetzungsvorlage).

Es war nicht die eleganteste Lösung und es musste ein Programm installiert werden, was ein Nachteil ist. Aber sobald ich herausfand, was um mich herumging, funktionierte es wie ein Zauber (und fand 3 Dateien von ungefähr 2300, die mit BOM waren).