我有 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替换任何出现的 textb[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
我认为这非常简单。如果您有疑问,请告诉我。