Home > OS >  awk script for copy/paste part of string
awk script for copy/paste part of string

Time:01-30

I have several config files that need to be edited with awk or sed. The first line contains several letters in place after ":" and end with "]" ProgramName. I need to copy ProgramName to the third line right after command=docker-compose run --rm --name.

Input:

[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name

target output:

[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name ProgramName

I do not have the necessary experience in awk and ask for help from you.

CodePudding user response:

If ed is available/acceptable, something like:

#!/bin/sh

ed -s file.txt <<-'EOF'
  /^\[program:.*\]$/t/^command=/
  s/^\[.*:\(.*\)\]$/ \1/
  -; j
  ,p
  Q
EOF

In one-line

printf '%s\n' '/^\[program:.*\]$/t/^command=/' 's/^\[.*:\(.*\)\]$/ \1/' '-; j' ,p Q |  ed -s file.txt

  • Change Q to w if in-place editing is required.

  • Remove the ,p to silence the output.

CodePudding user response:

I would harness GNU AWK for this task following way, let file.txt content be then

[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name

then

awk 'BEGIN{FS="]|:|\\["}/^\[program:/{name=$3;n=NR}NR==n 3{$0=$0 " " name}{print}' file.txt

gives output

[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name ProgramName

Explanation: I inform GNU AWK that field separator (FS) is ] or : or [ then for line starting with [program: I store third column value as name and number of row (NR) as n, then for line which is three lines after thtat happen i.e. number row equals n plus three I append space and name to line and set that as line value, for every line I print it. Be warned that it does modify

to the third line

to comply with your requirement, therefore make sure it is right place do change for all your cases.

(tested in GNU Awk 5.0.1)

CodePudding user response:

gawk -i inplace '
    BEGIN { RS = ORS = ""; FS = OFS = "\n" }
    match($1, /^\[program:(.*)\]/, a) {
        for (i = 2; i <= NF;   i)
            if ($i ~ /^command=docker-compose run --rm --name/)
                $i = "command=docker-compose run --rm --name " a[1]
    }
    { print $0 RT }' file

Study the GNU Awk manual for details.

  • Related