Bash

如何在bash中從/向文件列印文字字元?

  • February 3, 2018

我想按字元過濾文件(為了刪除我無法控制生成的無效 xml 字元),但我似乎什至無法將單個字元從一個文件複製到另一個文件。我printf以前複製包括輸入在內的文字部分,但現在它不會將輸入複製為一個,而是複制為一些空長度的字元串。我的程式碼:

infile=$1
outfile=$2
touch $outfile
while IFS= read -r -n1 char
do
       # display one character at a time
       printf "%s" "$char" >> $outfile
done < "$infile"
diff $infile $outfile

我不介意使用 sed 或 awk,但我必須對允許的字元進行編碼。 Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

輸入不應該是一個問題,read應該讀它就好了。換行符(換行符)是,因為它是read. 您可以使用該read -d ''技巧使其工作。

echo $'\r' | { IFS= read -r -n1 x; echo "$x"|xxd; }          # CR
echo $'\n' | { IFS= read -r -n1 x; echo "$x"|xxd; }          # LF fails
echo $'\n' | { IFS= read -d '' -r -n1 x; echo "$x"|xxd; }    # LF ok

但是,就像他們說的那樣,你可能不想在 shell 中做這樣的事情。tr這正是刪除一組固定字元所需要的,但至少 GNUtr適用於字節,而不是字元,因此它對 Unicode 沒有多大用處。

如果您的語言環境正確設置為 UTF-8,我認為這個 Perl 應該適用於 UTF-8 數據:

perl -C -pe 'tr/\x09\x0a\x0d\x20-\x{d7ff}\x{e000}-\x{fffd}\x{10000}-\x{10ffff}//cd' < in > out

但更好地測試它,我不習慣 Unicode 怪癖。

tr/abc//cd``abc刪除(tr///實際上是為了將字元轉換為其他字元,請參閱perlop)中未列出的字元。它接受字元列表以及範圍,並表示具有十六進制值HH的字元,以及具有值HHHH的字元。所以上面接受, , , 從to等的一切。\x*HH*``\x{*HHHH*}``0x09``0x0a``0x0d``0x20``0xd7ff

上面的列表直接取自問題中提供的列表。我會把它留給最終使用者來評估是否應該改變它。

引用自:https://unix.stackexchange.com/questions/421286