无法在 shell 脚本中 grep 外语

无法在 shell 脚本中 grep 外语

我是 shell 脚本编写的新手,我有一个文本,其中包含以下格式的文本:-

"some foreign language",'corresponding ID to text'

例如:-

"Назад",IDC_SSB_DLG_BACK_BTN

我需要找到与 ID 相关的文本并将其保存在文本文件中。

这是我的示例脚本:-

#!/bin/sh
target_file=$1
output=$2
translationID=IDC_SSB_DLG_BACK_BTN
translation=$(cat $target_file | grep $translationID)
translationValue=$(echo "$translation" | awk -F',' '{print $1}')
translationValueFinal=$(echo "$translationValue" | tr -d '"')
echo "$translationValueFinal" >> $output

运行此脚本时出现错误:-grep: (standard input): binary file matches

请建议一种在 shell 脚本中 grep 并保存外语的方法。谢谢

答案1

如果您使用 GNU grep,则可以告诉 grep 将输入视为文本,无论遇到什么字符。

grep -a

但输入中似乎有一些非文本字节,因此最好检查输入文件。

答案2

不要grep为此使用一堆额外的代码,因为您想要在特定字段上进行文字字符串匹配,而 grep 本身无法做到这一点,并且可以做到这一点的工具不需要其他工具的帮助。

您现有的命令:

translationID=IDC_SSB_DLG_BACK_BTN
grep $translationID

即使我们添加了缺少"sgrep "$translationID"如果满足以下任一条件,则它将失败:

  1. 第一个字段中的字符串与 id 匹配,例如IDC_SSB_DLG_BACK_BTN,any, 或
  2. 任一字段中的字符串都包含一个不同的字符串,该 ID 是该字符串的子字符串,例如any,FOOIDC_SSB_DLG_BACK_BTNBARFOOIDC_SSB_DLG_BACK_BTNBAR,any
  3. 第二个字段中的字符串和 ID 变量包含正则表达式元字符,例如any,foo.barany,foodbar都会匹配translationID=foo.bar

可能还有其他人。看如何找到与模式匹配的文本有关其中一些类型问题的更多信息。

使用此输入文件,例如:

$ cat file
any1,foodbar
foo.bar,any2
foofoo.barbar,any3
any4,foofoo.barbar
"Назад",foo.bar

当第二个字段是字符串时foo.bar(即上面的最后一行),我们要打印第一个字段的值:

$ translationID=foo.bar

这是您的grep命令,它找到了预期的行,但也进行了许多错误的匹配,因此输出了不需要的行:

$ grep "$translationID" file
any1,foodbar
foo.bar,any2
foofoo.barbar,any3
any4,foofoo.barbar
"Назад",foo.bar

与此awk命令仅匹配正确的行(以及仅输出所需的字段):

$ awk -F',' -v id="$translationID" '$2==id{print $1}' file
"Назад"

或者,如果您想删除引号,有很多选项,包括:

$ awk -F'[,"]+' -v id="$translationID" '$3==id{print $2}' file
Назад

该 awk 命令正在对目标字段进行全字段文字*字符串比较,因此它是准确的,而 grep 命令正在执行部分行正则表达式比较,除非您对输入值很幸运,否则有时会失败。

*轻微警告 - 如果translationID包含您想要字面处理的反斜杠,那么您需要执行以下操作:

$ id="$translationID" awk -F',' '$2==ENVIRON["id"]{print $1}' file
"Назад"

或类似的替代方案,请参阅如何在 awk 脚本中使用 shell 变量

如果您的输入文件可以包含 NUL 字符,那么使用 GNU awk 或其他一些 awk 来记录它们支持的内容,因为 awk 是一个文本处理工具,因此只需要使用文本文件作为输入,并且根据 POSIX 定义,文本文件不能包含UL 字符,并且使用 GNU awk 您可能需要设置宾模式,例如:

awk -v BINMODE=3 -F',' -v id="$translationID" '$2==id{print $1}' file

相关内容