使用另一个文件中的第 n 行从两个字符串之间的任何内容中替换第 n 个出现

Replace each nth occurs from anything between two strings using nth line from another file

我实际上想在 0.txt 文件中每隔 nth 替换两个字符串 group_tree ()\t", 之间的任何内容使用来自另一个文件 1.txtawk.

nth

这类似于

我一直在寻找一些东西,我试图改编这个 ,但我不知道它是如何为我寻找的东西工作的。这是我的尝试:

awk \

'NR==FNR {a[NR]=[=10=]; next} /^group_tree(/ /{gsub("tortoise", a[++i])} /^)\t",/1' \
    1.txt 0.txt

不要只生成任何结果消息:

Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:      GNU long options: (standard)
.....

我的源文件:

0.txt:

"#sun\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"#sun\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",

1.txt:

(food, apple,)(bag, tortoise,)
(sky, cat,)(sun, sea,)
(car, shape)(milk, market,)
(man, shirt)(hair, life)
(dog, big)(bal, pink)

我想要的输出 2.txt:

"#sun\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((sky, cat,)(sun, sea,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((car, shape)(milk, market,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((man, shirt)(hair, life))\t",
"machine(shoes_shirt.shop)\t",
"#sun\t",
"car_snif = house.group_tree((dog, big)(bal, pink))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((sky, cat,)(sun, sea,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((car, shape)(milk, market,))\t",

调用 awk 时收到的错误消息是因为 awk \ 和脚本之间有一个空行,所以这就像调用 awk 时没有脚本也没有参数。如果您将其更改为:

awk \

'NR==FNR {a[NR]=[=10=]; next} /^group_tree(/ /{gsub("tortoise", a[++i])} /^)\t",/1' \
    1.txt 0.txt

对此:

awk \
'NR==FNR {a[NR]=[=11=]; next} /^group_tree(/ /{gsub("tortoise", a[++i])} /^)\t",/1' \
    1.txt 0.txt

或更惯用的说法是:

awk '
    NR==FNR {a[NR]=[=12=]; next} /^group_tree(/ /{gsub("tortoise", a[++i])} /^)\t",/1
' 1.txt 0.txt

然后您将不会再收到该错误消息(但您会收到不同的错误消息,因为脚本仍然包含语法错误)。

不过,要解决您的实际问题,请使用 GNU awk 作为 match()ARGIND:

的第三个参数
$ cat tst.awk
ARGIND == 1 {
    newVals[++totNew] = [=13=]
    next
}
match([=13=],/(.*group_tree\().*(\)\t",.*)/,a) {
    newIdx = ( (++numNew - 1) % totNew ) + 1
    [=13=] = a[1] newVals[newIdx] a[2]
}
{ print }

$ awk -f tst.awk 1.txt 0.txt
"#sun\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((sky, cat,)(sun, sea,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((car, shape)(milk, market,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((man, shirt)(hair, life))\t",
"machine(shoes_shirt.shop)\t",
"#sun\t",
"car_snif = house.group_tree((dog, big)(bal, pink))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((food, apple,)(bag, tortoise,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((sky, cat,)(sun, sea,))\t",
"machine(shoes_shirt.shop)\t",
"car_snif = house.group_tree((car, shape)(milk, market,))\t",

上面假设每个 group_tree(.

之后只有一个 )\t",

POSIX awk:

awk '
FNR==NR {a[i++] = [=10=]}
FNR!=NR {if (sub(/group_tree[[:space:]]*\(.*\)\t",$/,
             "group_tree("a[j%i]")\t\"")) {j++}
         print}' 1.txt 0.txt

您的描述在 group_tree( 之间有一个 space,但您的示例数据没有。我允许这两种情况。

由于两种模式之间的贪婪 .*,这并不完全可靠。如果您的所有数据都与示例相似,可能没问题。

请注意,无论 sub 是否成功,sub(/foo/, a[j++]) 都会迭代 j