Sed 错误用变量替换部分字符串

Sed 错误用变量替换部分字符串

我有 3 个文本文件。我想file3在 in 中搜索字符串并将其替换为find 中file2的字符串。file1我需要在file1中的字符串末尾附加一个自定义标记file3,替换从 中找到的部分字符串file2

file3

aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=arn:aws:iam::XXXXX:root
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=arn:aws:iam::XXXXX:user/user

file2

arn:aws:iam::XXXXX:root 
arn:aws:iam::XXXXX:user/user

file1

my_custom_tag_1
my_custom_tag_2

期望的输出:

aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_1
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_2

我尝试将文件中的行加载到数组中,并将索引包含在替换中sed

sed "s|${file2array[0]}|${file1array[0]}|g" file3.txt

但这会返回“没有先前的正则表达式”错误。我还尝试使用 for 循环将数组索引写入唯一变量,并对变量使用与上面相同的方法

sed "s|$var2|$var1|g" file3.txt

这也失败了

有趣的是,

sed "s|${file2array[0]}|customtext}|g" file3.txt

失败但是

sed "s|customtext|${file1array[0]}|g" file3.txt

成功了。

任何帮助是极大的赞赏。现在已经为此工作了几十个小时。

答案1

尝试:

awk 'FNR==NR{a[FNR]=$0; next} NR<=length(a)+FNR{b[FNR]=$0; next} {for (i=1;i<=length(a);i++) gsub(a[i], b[i])} 1' file2 file1 file3

例如:

$ awk 'FNR==NR{a[FNR]=$0; next} NR<=length(a)+FNR{b[FNR]=$0; next} {for (i=1;i<=length(a);i++) gsub(a[i], b[i])} 1' file2 file1 file3
aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_1
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_2

怎么运行的

  • FNR==NR{a[FNR]=$0; next}

    这会将 file2 中的所有行保存在 array 中a

    FNR 是从当前文件读取的行数。 NR 是总共读取的行数。因此,如果FNR==NR,我们正在读取第一个命名文件file2. a[FNR]=$0将当前行(表示为 )添加到键 FNR 下的$0数组中。a

    该命令next告诉 awk 跳过剩余的命令并重新开始next

  • NR<=length(a)+FNR{b[FNR]=$0; next}

    这会将 file1 的所有行保存在 array 中b

    在这里,我们使用类似的测试NR<=length(a)+FNR来确定我们是否正在读取第二个文件。 b[FNR]=$0将当前行(表示为 )添加到键 FNR 下的$0数组中。b

    该命令next告诉 awk 跳过剩余的命令并重新开始next

  • for (i=1;i<=length(a);i++) gsub(a[i], b[i])

    如果我们到达这里,我们正在读取第三个文件。这会将与 file2 中的行匹配的任何文本替换为 file1 中的相应文本。

    循环for (i=1;i<=length(a);i++)遍历数组中每一行的行号a

    gsub(a[i], b[i])a[i]用 text替换任何出现的 text b[i]

    请注意,file2 中的文本被视为正则表达式。如果您需要在此文件中包含任何正则表达式活动字符,则应对它们进行转义。

  • 1

    这是 awk 的 print-the-line 的神秘简写。

答案2

我会写

awk '
  BEGIN { FS = OFS = "=" }
  FILENAME == "file1" {
    tag[FNR] = $0
  }
  FILENAME == "file2" {
    str[$0] = FNR
  }
  FILENAME == "file3" {
    if ($NF in str) $NF = tag[str[$NF]]
    print
  }
' file1 file2 file3

我认为这非常简单。如果您有疑问,请告诉我。

相关内容