[英]bash and awk extract string at specific position in non-utf file
我有一個用chatset ISO-8859-1
編碼的文件foo.txt
。 我正在使用awk
進行一些字段提取,基於特定的 position。例如,在每一行中,提取一個從 pos 10 開始、長度為 5 的字符串。
這是一項簡單的任務,但是以下命令在不同的 Linux 機器(具有不同的 bash/awk 版本)中具有不同的行為。
在Machine 1 OK中,Machine 2 NOT ok:
cat foo.dat | iconv -f ISO-8859-1 -t UTF-8 | awk '{print substr($0, 10,5)}' > results.utf8
在機器 1 中不正常,機器 2 正常:
cat foo.dat | awk '{print substr($0, 10,5)}' | iconv -f ISO-8859-1 -t UTF-8 > results.utf8
如果我使用相同的輸入文件運行相同的命令,則在“剪切”位置之前包含“非 utf”字符(如 (a▒c))的每一行的結果都是不同的”。
不知道問題出在哪里,linux Kernel、bash 或 awk 版本……特別是如何使用通用方法提取所需的字符串……
不知道問題出在哪里,linux Kernel、bash 或 awk 版本...
POSIX 標准要求
awk
function 是字符,而不是字節。 因此,在gawk
中,length()
、substr()
、split()
、match()
和其他字符串函數 (...) 都根據本地字符集中的字符而不是字節來工作。 (但並非所有awk
實現都這樣做)。
如果以上成立,那么回答如何有一個通用的方法來提取所需的字符串是使用符合 POSIX 的AWK
實現(或者至少尊重上述規則以字符而不是字節的方式工作)並確保本地字符集正如所願。
一種選擇是使用一種只有一種實現的語言,您可以在其中關閉 UTF-8(或者更確切地說,無法將其打開)。
目前還不完全清楚你期望 output 是什么,但我猜你想要這樣的東西:
perl -lne 'print substr($_, 9, 5)' foo.dat | iconv -f ISO-8859-1 -t UTF-8
請注意轉換是如何僅在提取之后發生的,因此您可以確保每個字節恰好是一個字符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.