3

I need to use awk to print the columns containing multiple patterns. I need to print column #2 as well as all the columns containing "config" and "service" respectively.

File content:

    build 345 java groovy /test:fail.txt /config:launcher.mxres /nickname:prod /service:session 
    auto 4986 java -xmx512 -d64 /test:pass.txt /nickname:deal /service:engine /config:launcher5.mxres
    build 912 binary.exe -f -t /test:code.txt /config:launcher_binary.mxres /service:scanner /nickname:input 

Output:

    345 /config:launcher.mxres /service:session
    4986 /config:launcher5.mxres /service:engine
    912 /config:launcher_binary.mxres /service:scanner
0

1 Answer 1

7

The following awk script will go through the fields (columns) of each line and look for the /config: and /service: fields. When found, the full content of these fields are stored in variables.

Once the fields have been processed, the script outputs the data in the second field together with the found fields from the loop. The process then continues with the next line of input.

{
    config = service = "";

    for (i = 3; i <= NF; ++i) {
        if ($i ~ "^/config:") {
            config = $i;
        } else if ($i ~ "^/service:") {
            service = $i;
        }
    }

    print $2, config, service;
}

This script has been tested and works with gawk (GNU awk), mawk (Mike's awk) and nawk (BSD awk).

Running this on the data that you supplied:

$ awk -f script.awk data
345 /config:launcher.mxres /service:session
4986 /config:launcher5.mxres /service:engine
912 /config:launcher_binary.mxres /service:scanner

If you want tab-delimited output, add BEGIN { OFS = "\t" } at the top of the script.

... or you could pass the output of the original script through column -t (will insert multiple spaces if needed to align columns):

$ awk -f script.awk data | column -t
345   /config:launcher.mxres         /service:session
4986  /config:launcher5.mxres        /service:engine
912   /config:launcher_binary.mxres  /service:scanner

As a one-liner:

$ awk '{ config = service = ""; for (i = 1; i <= NF; ++i) { if ($i ~ "^/config:") { config = $i } else if ($i ~ "^/service:") { service = $i } } print $2, config, service }' data | column -t
5
  • I need the solution in one command line and not a script please Commented Jan 26, 2017 at 9:36
  • @ekassis Sorted. Commented Jan 26, 2017 at 9:41
  • 4
    @kusalananda, you're too good to him Commented Jan 26, 2017 at 9:46
  • @J.Chomel I know. I'm a nice guy. It's a problem I have. Commented Jan 26, 2017 at 9:48
  • thank you @Kusalananda it works fine but with the / instead of " and I removed the column -t since I don't have it. $ awk '{ config = service = ""; for (i = 1; i <= NF; ++i) { if ($i ~ /^\/config:/) { config = $i } else if ($i ~ /^\/service:/) { service = $i } } print $2, config, service }' data Commented Jan 26, 2017 at 9:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.