我有一个带有以下内容的file1.txt:
time="2016-04-25T17:43:11Z" level=info msg="SHA1 Fingerprint=9F:AD:D4:FD:22:24:20:A2:1E:0C:7F:D0:19:C5:80:42:66:56:AC:6F"
我希望文件如下所示:
9F:AD:D4:FD:22:24:20:A2:1E:0C:7F:D0:19:C5:80:42:66:56:AC:6F
实际上,我需要将命令作为字符串传递。这就是为什么bash命令需要封装在带双引号的字符串中的原因。但是,当我包括
时 " grep -Po '(?<=Fingerprint=)[^"]*' "
我没有得到所需的输出。似乎我需要正确地避开双引号。
答案 0 :(得分:5)
要回答 literal 问题,您可以使用反斜杠来逃避命令中的双字引号。但是,由于BashFAQ #50中给出的原因,这种做法非常糟糕:
# Avoid this absent a very good reason
grep_cmd_str="grep -Po '(?<=Fingerprint=)[^\"]*'"
eval "$grep_cmd_str" <file1.txt # eval is necessary, with all the issues that implies
当你需要存储一个简单的命令(没有重定向或其他shell结构)时,更好的做法 [1] 在变量中是使用数组 [2] ,而不是标量变量,用于保存其参数:
# Use this principally if you need to dynamically build up an argument list
grep_args=( grep -Po '(?<=Fingerprint=)[^"]*' )
"${grep_args[@]}" <file1.txt
如果您没有任何要求您使用上述任何一项的约束,请考虑一个函数(只要它们是硬编码的,它允许重定向和shell构造):
# Use this whenever possible, in preference to the above
grep_fp() { grep -Po '(?<=Fingerprint=)[^"]*' "$@"; }
grep_fp <file1.txt
[1] - 在此上下文中,不评估shell构造是一个安全功能:它可以保护您免受恶意文件名或类似内容的影响,这些内容已替换为您正在使用的值作为一个命令。
[2] - 请注意,POSIX sh中没有数组,您的问题也会被标记为。也就是说,通过覆盖"$@"
可以获得类似的功能(可能在有限的范围内,例如函数,以保留其原始值)。