繁体   English   中英

使用 grep/awk/sed 查找确切的 shell 变量

[英]Finding the exact shell variable with grep/awk/sed

我试图找到包含反斜杠和空格的某个字符串的精确匹配,但我似乎无法获得只返回一个匹配的正确技术(参见示例)。 问题出现在同一变量有更多“版本”的地方,如下所示。

变量的两个例子是:
variable_i_want="Database\\Base\\location of site"
variable_dont_want="Database\\Base\\location of site - remote"

我正在搜索的文件结构如下(所有列都由制表符分隔):

Database\Base\location of site             data1    data2    data3   
Database\Base\location of site - remote    data1    data2    data3  
Other_variable\something                   data1    data2    data3

在这种情况下,我的目标是只匹配第一行。
到目前为止我尝试过的事情:

awk -v pattern="$variable_i_want" -F\\\\t '$1~pattern {print $1,$2,$3}' file.txt
返回
awk: warning: escape sequence '\\B' treated as plain 'B'

grep -F "$variable_i_want" file.txt
返回包含两个匹配项(站点位置和站点位置 - 远程)的行。 省略 -F 不会返回任何内容,因为它将反斜杠和空格解释为代码而不是字符串(我猜)

我认为可能的解决方案是将变量与正则表达式相结合,例如^$variable_i_want$但我无法在 sed/awk 或 grep 中使用它。

所以,为了清楚起见:我希望包含$variable_i_want的行匹配。

与 OP 交谈后,知道他/她的操作系统是 Ubnutu,因此使用 Ubuntu 16.04.6 编写并测试了此代码

variable_dont_want='Database\\Base\\location of site - remote'
variable_i_want='Database\\Base\\location of site'

现在运行以下代码:

awk -v var="$variable_i_want" -v var1="$variable_dont_want" 'index($0,var) && !index($0,var1)' Input_file

上述代码的输出如下。

Database\Base\location of site             data1    data2    data3

所以我们需要在这里做两件事来使这个工作与awk工作:

  • 将 bash 变量用单引号括起来,而不是"\\作为文字字符,我们需要告诉变量我们需要其中的 2 个\\
  • 现在为什么我们需要让变量理解读取\\ as \\\\因为awk它应该被转义,以便awk不会给出警告消息等。

如果你有 bash 4.4 或更高版本,你可以做

grep "^${variable_i_want@Q}$"$'\t' file.txt

^匹配行的开头, $'\\t'匹配制表符(注意,这必须在原始引号之外......)。 ${...@Q}以 grep 接受的方式转义反斜杠和空格。 如果您有旧版本的 bash,则可以使用printf %q代替:

grep "^$(printf %q "$variable_i_want")"$'\t' file.txt

或者

grep "^$(printf "%q\t" "$variable_i_want")" file.txt

(因为无论如何你都在使用 printf,你可以让它输出一个文字制表符......)

例子:

tmp> more file.txt
blah
Database\Base\location of site  data1   data2   data3
Database\Base\location of site - remote data1   data2   data3

tmp> printf "%q\n" "$variable_i_want"
Database\\Base\\location\ of\ site

tmp> grep "^$(printf "%q" "$variable_i_want")"$'\t' file.txt
Database\Base\location of site  data1   data2   data3

您可能想要转义\\B并使用$强制它位于钩子的末尾。

awk -F\\t '$1~/Database\\Base\\location of site$/ {print $1,$2,$3}' file.txt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM