簡體   English   中英

bash 和 awk 在非 utf 文件中提取特定 position 處的字符串

[英]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 版本...

GNU 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM