Home > Software engineering >  Replace each nth occurs from anything between two strings using nth line from another file
Replace each nth occurs from anything between two strings using nth line from another file

Time:11-09

I would actually like to replace anything that is between two strings, group_tree ( and )\t", on the 0.txt file every nth occurrence using the nth line from another file 1.txt through awk.

This would be something like Replace each nth occurrence of 'foo' by numerically respective nth line of a supplied file

I've been looking for something, I tried to adapt this https://stackoverflow.com/a/21876700/10824251, but I have no idea how it works for what I look for. Here my attempts:

awk \

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

Do not generate any result just the message:

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)
.....

My sources files:

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)

My desired output 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",

CodePudding user response:

Using GNU awk for the 3rd arg to match() and ARGIND:

$ cat tst.awk
ARGIND == 1 {
    newVals[  totNew] = $0
    next
}
match($0,/(.*group_tree\()[^)] (\)\\t",.*)/,a) {
    newIdx = ( (  numNew - 1) % totNew )   1
    $0 = 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",

The above assumes there's only one )\t", after each group_tree(.

CodePudding user response:

POSIX awk:

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

Your description has a space between group_tree and (, but your example data does not. I allowed for either case.

This is not completely robust, due to greedy .* between the two patterns. Probably okay if all your data is similar to the example.

Note that sub(/foo/, a[j ]) iterates j whether sub succeeds or not.

  • Related