简体   繁体   中英

How to use sed/awk commands to cut a string and append to the succeeding lines?

Need your help in fixing one issue which I am facing while writing a shell script.

In a text file, I have the content as below :

Deployment ' wonderful '

mon_z1/0 (c99-2230-333) running

mon_z1/1 (24a90-00d) running

mon_z1/2 (4b2-86a5fb2) running

Deployment ' rainbow '

post_m (333-33-22sd) running

post_s (8-333-33d) running

===================================

I am looking for an output something like this - where deployment name should append to the running states : Example :

wonderful : mon_z1/0 (c99-2230-333) running

wonderful : mon_z1/1 (24a90-00d) running

wonderful : mon_z1/2 (4b2-86a5fb2) running

rainbow : post_m (333-33-22sd) running

rainbow : post_s (8-333-33d) running

Please help how I can achieve with sed or awk commands

awk solution:

awk '/Deployment/{ gsub("\047","",$2); d=$2; next }$3~/running/{ print d,":",$0 }' file

The output:

wonderful : mon_z1/0 (c99-2230-333) running
wonderful : mon_z1/1 (24a90-00d) running
wonderful : mon_z1/2 (4b2-86a5fb2) running
rainbow : post_m (333-33-22sd) running
rainbow : post_s (8-333-33d) running

  • /Deployment/{...} - perform an action on encountering Deployment line

  • gsub("\\047","",$2) - remove single quotes from Deployment name

  • d=$2 - capture Deployment name

  • $3~/running/ - on encountering line with running state - print the line with related Deployment name

Here is another awk solution:

awk 'BEGIN{FS="\047"}/^Deployment/{ x = $2; next }$0 != ""{ print x, ":" ,$0 }' file 

Output:

wonderful : mon_z1/0 (c99-2230-333) running
wonderful : mon_z1/1 (24a90-00d) running
wonderful : mon_z1/2 (4b2-86a5fb2) running
rainbow : post_m (333-33-22sd) running
rainbow : post_s (8-333-33d) running

It is similar to the one from RomanPerekhrest. The difference is that I'am filtering out empty strings with:

$0 != "" 

That takes care that the action is only performed on lines that are not empty.

You asked for sed or awk, but I'm going to provide an example in perl which is easily translated to awk. The trick is how you access the match (the name of the deployment). You can use a technique like RomanPerekhrest and remove the ' marks from the 2nd field, or you can use regular expression matching and take the deployment name from the match group. This is what I did, because it's very simple in perl. As a command line:

cat data | perl -e "use warnings; use strict; my \$deployment; while (<>) { if (\$_ =~ /^Deployment '(.*)'/) { \$deployment = \$1; } else { print(\"\$deployment: \$_\n\"); } }"

Or, rewritten for clarity:

use warnings;
use strict;

my $deployment;

while (<>) {
    if ($_ =~ /^Deployment '(.*)'/) {
        $deployment = $1;
    } else {
        print("$deployment: $_\n");
    }
}

But do note that when you rewrite this in awk, you don't need the while loop. Awk's main strength is that it implicitly loops over each line and splits it into fields.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM