在特定行的另一个变量文本之后插入变量文本

在特定行的另一个变量文本之后插入变量文本

我正在尝试在特定行上的另一个变量文本之后插入变量文本。以下是迄今为止我的尝试,据我所知,如果我可以转义引号,以便awk可以看到变量并仍然应用该变量,那么它应该可以工作,但我不知道该怎么做:

#!/bin/sh

VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)

awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt

答案1

要将字符串传递给 awk 脚本,请通过环境变量传递它们。

export VAR VAR1
awk '
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

我重新组织了你的脚本以使逻辑更简单。我还用字符串比较替换了正则表达式匹配:使用正则表达式匹配,$VAR将被视为正则表达式,它不会执行字符串比较。甚至/$VAR/不会使用您需要的值VAR(这是 Perl 语法,而不是 awk)match($0, VAR)

关于其他一些实际上不起作用的解决方案的注释(仅当变量不包含任何特殊字符时它们才起作用,哪个字符是特殊字符取决于方法):

  • awk -v awkvar="$VAR" '$0 == awkvar …'展开行内容中的反斜杠。
  • awk "/$VAR/" …使 shell 将 的值扩展VAR为 awk 片段。例如,如果file.txt包含则执行^/ {system("touch ~/naughty")} /该命令。touch ~/naughty

另一种方法是让 awk 读取所有文件。

awk '
    BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
    NR == 1 {VAR = $0}
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

答案2

一种可能的 AWK 解决方案:

   awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'

打破所有外部变量周围的 ' 引号。

像另一篇文章建议的传递变量的另一个可能的解决方案是将 VAR1 作为 awk 变量传递,但我认为您仍然需要使用 VAR 对模式进行单引号块转义:

 awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'

您可以尝试使用 sed :) 它是专门为这种替换而设计的。

 sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt     

如果您可以在一行上有多个 VAR 实例,则在 sed 命令末尾添加 g (全局),这样它就不会在找到的第一个匹配处停止:

 sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt 

重要!:确保 '/' 字符不会出现在 VAR 或 VAR1 变量中,如果可以,您需要将它们转义为 awk 或 sed,或者使用 sed,您可以将命令的分隔符更改为其他内容,例如 '; '例如:

 sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt

sed 命令的解释:
我们在 sed 命令周围使用双引号“而不是单引号,这样像 VAR 和 VAR1 这样的变量将被它们的值替换。这发生在 sed 执行命令之前,这就是为什么如果 / 可以出现在您需要寻址的变量内容中(对于 awk 也是如此)
's' 表示您编写以下形式的替换命令:
s/<pattern>/<replacement pattern>/
'/ ' 紧跟在 s 后面的是用于分隔命令各部分的分隔符,因此如果您放置 ; ,则必须像上面所示那样使用 ; 来匹配 $VAR 变量的内容。模式是\0,这意味着打印模式匹配的新行'\n'和VAR2的内容。

哎呀没有看到关于下面的行的部分..固定模式。

答案3

如果你想使用awk,你必须使用选项传递bash变量: awk-v

awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt

但请检查 Rob 的答案以获得更正确和详细的解决方案。

相关内容