Mam plik w kodowaniu UTF-8 z BOM i chcę usunąć BOM. Czy istnieją jakieś narzędzia wiersza polecenia systemu Linux do usunięcia BOM z pliku?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
Mam plik w kodowaniu UTF-8 z BOM i chcę usunąć BOM. Czy istnieją jakieś narzędzia wiersza polecenia systemu Linux do usunięcia BOM z pliku?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
Odpowiedzi:
Jeśli nie masz pewności, czy plik zawiera BOM UTF-8, to (przy założeniu implementacji GNU sed) usunie BOM, jeśli istnieje, lub nie wprowadzi żadnych zmian, jeśli nie będzie.
sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt
Możesz również zastąpić istniejący plik -iopcją:
sed -i '1s/^\xEF\xBB\xBF//' orig.txt
en_US.UTF-8ustawieniami regionalnymi i działało. Kiedy to zawiedzie?
-<U+FEFF>\chapter{xxx}Po: +\chapter{xxx}^M Objaśnienie: Używanie słowa MS do literówek w pliku lateksu. Lateks pod Linuksem pokazuje wspomniane błędy. Dane wyjściowe pochodzą z systemu git. Jak mogę zmienić wyrażenie, aby uchwycić ten szczególny przypadek?
LM nie ma sensu w UTF-8. Są one zazwyczaj dodawane przez pomyłkę przez fałszywe oprogramowanie w systemach operacyjnych Microsoft.
dos2unix usunie go, a także zadba o inne osobliwości plików tekstowych Windows.
dos2unix test.xml
dos2unix?
Możliwe jest usunięcie BOM z pliku za pomocą tailpolecenia:
tail -c +4 withBOM.txt > withoutBOM.txt
tailużywa indeksowania opartego na 1 ?! WTF!
tail -c -1lub tail -c 1(co tailjest zwykle używane) to treść zaczynająca się od ostatniego bajtu, tail -c +1zaczynająca się od pierwszego bajtu. tail -c 0/ tail -c +0ponieważ byłoby to o wiele bardziej nieintuicyjne.
(dd bs=1 count=3 of=/dev/null; cat) <input >output. Lub z GNU (head -c3 >/dev/null; cat)- nawet w UTF8 lub innych ustawieniach narodowych innych niż jednobajtowe; GNU head robi „char” = bajt.
Otwórz plik w VIM:
vi text.xml
Usuń kodowanie BOM:
:set nobomb
Zapisz i wyjdź:
:wq
<feff>, ale :set nobombgo nie modyfikuje ani nie usuwa.
Możesz użyć
LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename
aby usunąć znak kolejności bajtów z początku pliku, jeśli taki istnieje, a także przekonwertować dowolne nowe wiersze CR LF tylko na LF. LANG=C LC_ALL=CMówi powłoce chcesz polecenie do uruchomienia w lokalizacji domyślnej C (znany również jako domyślna POSIX locale), gdzie trzy bajty tworzące Byte Order Mark traktowane są jako bajty. -iOpcja sed znaczy w miejscu. Jeśli używasz -i.old, to sed zapisuje oryginalny plik jako filename.old, a nowy plik (z ewentualnymi modyfikacjami) jako filename.
Osobiście lubię to mieć jako ~/bin/fix-ms; na przykład jako
#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
for FILE in "$@" ; do
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
done
else
exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi
więc jeśli muszę to zastosować, aby powiedzieć wszystkie pliki źródłowe C i nagłówki (na przykład mój stary kod z ery MS-DOS!), po prostu uruchamiam
find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix
lub, jeśli chcę tylko spojrzeć na taki plik, bez modyfikacji, mogę uruchomić
~/bin/ms-fix < filename | less
i nie widzę brzydkiego <U+FEFF>w moim terminalu UTF-8.
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"?
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"nie działa; zwraca kod wyjścia, ale przed wyjściem przetwarza wszystkie pliki wymienione na liście argumentów.
--Przed nazwami plików jest oczywiście ważne: bez nich nazwy plików zaczynające się od myślnika mogą być uważane za opcje przez sed. Zredagowałem je w mojej odpowiedzi; dziekuje za przypomnienie!
Niedawno znalazłem to małe narzędzie wiersza polecenia, które dodaje lub usuwa BOM w dowolnych plikach zakodowanych w UTF-8: UTF BOM Utils ( nowy link na github)
Mała wada, możesz pobrać tylko zwykły kod źródłowy C ++. Musisz utworzyć plik makefile ( na przykład z CMake ) i skompilować go samodzielnie, na tej stronie nie ma plików binarnych.