我需要使用egrep
来获取索引文件中的条目。
为了找到条目,我使用以下命令:
egrep "^$var_name" index
$var_name
是从var列表文件中读取的变量:
while read var_name; do
egrep "^$var_name" index
done < list
其中一个可能的键通常采用以下格式:
$ERROR['SOME_VAR']
我的索引文件格式为:
$ERROR['SOME_VAR'] --> n
其中n
是找到变量的行。
问题是$var_name
在读取时会自动转义。当我启用调试模式时,我会执行以下命令:
+ egrep '^$ERRORS['\''SELECT_COUNTRY'\'']' index
上面的命令不起作用,因为egrep
会尝试解释模式。
如果我不使用扩展版本,使用grep
或fgrep
,该命令仅在我删除^
锚点时才有效:
grep -F "$var_name" index # this actually works
问题在于我需要以确保在该行的开头进行匹配。
想法?
答案 0 :(得分:1)
set -x
以shell表示法显示正在执行的命令。
您看到的反斜杠不成为参数的一部分,它们只是由set -x
打印,以可复制的格式显示已执行的命令。
你的问题不是太多逃避,而是太少:正则表达式中的$
表示&#34;行尾#34;所以^$ERROR
永远不会匹配任何内容。同样,[
]
是一个字符范围,与文字方括号不匹配。
与您的模式匹配的正确正则表达式为^\$ERROR\['SOME VAR']
,相当于egrep "^\\\$ERROR\['SOME_VAR']"
中的shell参数。
您可以选择解决此问题:
如果您希望能够在输入文件中使用正则表达式,则需要包含上述的正则表达式转义符,以便您的模式有效。
如果您希望能够使用任意的文字字符串,请使用可灵活匹配且字面匹配的工具。这需要跳过一些箍,因为遗留原因的UNIX工具非常草率。
这是一个有awk的人:
while IFS= read -r line
do
export line
gawk 'BEGIN{var=ENVIRON["line"];} substr($0, 0, length(var)) == var' index
done < list
它通过环境传递字符串(因为-v
很邋))然后从输入的开头按字面意思与字符串匹配。
这是一个示例调用:
$ cat script
while IFS= read -r line
do
export line
gawk 'BEGIN{var=ENVIRON["line"];} substr($0, 0, length(var)) == var' index
done < list
$ cat list
$ERRORS['SOME_VAR']
\E and \Q
'"'%@#%*'
$ cat index
hello world
$ERRORS['SOME_VAR'] = 'foo';
\E and \Q are valid strings
'"'%@#%*' too
etc
$ bash script
$ERRORS['SOME_VAR'] = 'foo';
\E and \Q are valid strings
'"'%@#%*' too
答案 1 :(得分:0)
您可以使用printf "%q"
:
while read -r var_name; do
egrep "^$(printf "%q\n" "$var_name")" index
done < list
更新:您也可以这样做:
while read -r var_name; do
egrep "^\Q$var_name\E" index
done < list
此处\Q
和\E
用于在文字字符串之间创建字符串,删除正则表达式符号的所有特殊含义。