我是 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"
如果满足以下任一条件,则它将失败:
- 第一个字段中的字符串与 id 匹配,例如
IDC_SSB_DLG_BACK_BTN,any
, 或 - 任一字段中的字符串都包含一个不同的字符串,该 ID 是该字符串的子字符串,例如
any,FOOIDC_SSB_DLG_BACK_BTNBAR
或FOOIDC_SSB_DLG_BACK_BTNBAR,any
。 - 第二个字段中的字符串和 ID 变量包含正则表达式元字符,例如
any,foo.bar
和any,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