简体   繁体   English

如何将带引号的字符串分配给 bash 中的变量,并将其用作 awk 中的模式?

[英]How can I assign a string with quotes to a variable in bash, and use it as a pattern in awk?

The command that I'm using is:我正在使用的命令是:

objects=shubham
awk -v myvar="$objects" '($0~myvar),/REPLACE/' a.txt

the a.txt file contains a.txt 文件包含

other-unwanted-content-here
target(shubham)
hello('shubham')
abc
bcd
REPLACE
other-unwanted-content-here

My desired output is:我想要的 output 是:

hello('shubham')
abc
bcd
REPLACE

...but I'm getting target(shubham) as well. ...但我也得到了target(shubham) How can I make hello('shubham') with the quotes be the place where awk starts matching?我怎样才能让带引号hello('shubham')成为 awk 开始匹配的地方?

Two approaches, depending on what you want.两种方法,取决于你想要什么。

  • Keep objects defined the way it is, amend your awk variable's assignment保持objects按原样定义,修改 awk 变量的赋值

    objects=shubham awk -v myvar="^hello[(]'$objects'[)]\$" '($0~myvar),/REPLACE/' <<'EOF'

    See this running at https://ideone.com/Bto1hBhttps://ideone.com/Bto1hB看到这个运行

  • Change objects to match only the target line更改objects以仅匹配目标行

    objects="^hello[(]'shubham'[)]\$" awk -v myvar="$objects" '($0~myvar),/REPLACE/' a.txt

    See this running at https://ideone.com/nF8MUlhttps://ideone.com/nF8MUl查看这个运行

Note that in either case, ~ in awk is a regex operator;请注意,无论哪种情况,awk 中的~都是正则表达式运算符; since in most regex forms (including POSIX ERE ) ( and ) are syntax, we had to change your string to be a regex that matches the desired line, instead of containing exactly that line itself.由于在大多数正则表达式中 forms (包括POSIX ERE()是语法,我们必须将您的字符串更改为与所需行匹配的正则表达式,而不是完全包含该行本身。 (Note that in both cases, the backslash before the $ in the regex is shell syntax, not regex syntax itself, necessary only because we're in double quotes; in single quotes those backslashes would need to be left out). (请注意,在这两种情况下,正则表达式中$之前的反斜杠是 shell 语法,而不是正则表达式语法本身,这只是因为我们在双引号中;在单引号中,这些反斜杠需要被省略)。

FWIW I'd do a full string rather than partial regexp comparison for robustness and use a flag instead of a range expression for efficiency and ease of future changes: FWIW 我会做一个完整的字符串而不是部分正则表达式比较以提高鲁棒性,并使用标志而不是范围表达式来提高效率和便于将来更改:

$ objects="hello('shubham')"
$ awk -v myvar="$objects" '$0==myvar{f=1} f; $0=="REPLACE"{exit}' a.txt
hello('shubham')
abc
bcd
REPLACE

Providing the pattern s are unique to the relevant lines, combining the variable in your starting line pattern (using && ) with /hello/ should fix the extra line problem:提供pattern s 对于相关行是唯一的,将起始行模式中的变量(使用&& )与/hello/组合应该可以解决额外的行问题:

awk -v myvar="$objects" '($0~myvar && /hello/),/REPLACE/' a.txt

output: output:

hello('shubham')
abc
bcd
REPLACE

Tested using mawk 1.3.4 on Raspberry Pi 400在 Raspberry Pi 400 上使用 mawk 1.3.4 进行测试

a generic awk solution allowing for partial matches that properly escapes all special characters for all awk variants without having to pre-escape them at the shell level:一个通用的awk解决方案允许部分匹配正确转义所有awk变体的所有特殊字符,而不必在 shell 级别预先转义它们:

# one of the cleaner ways to pass single-quoted single quotes 
# to awk since the octal codes aren't being interpreted by the shell  

___='??hello(\47sh{}u*[]bh(+)am\47)'
printf '%s' "other-unwanted-content-here 
             target(shubham)
             ??hello('sh{}u*[]bh(+)am')
             abc
             bcd
             REPLACE
             other-unwanted-content-here" |
 mawk2 -v ___="$___" 'BEGIN { _=(_="\\")_ gsub("[[-_:-/,-@{-~]", "["(__ = "&")"]",___) gsub("["(_)"^]", (_)__; ___), FS = ___ _*=_ } !_<NF, ____==$_' ____='REPLACE'
??hello('sh{}u*[]bh(+)am')
abc
bcd
REPLACE

The pair of regex -escaping gsub() s escapes more than what's needed because the alternative is a backslash nightmare这对regex - 转义gsub() s 转义比需要的更多,因为替代方案是反斜杠噩梦

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

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