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
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
  • I need the solution in one command line and not a script please – ekassis Jan 26 '17 at 9:36
  • @ekassis Sorted. – Kusalananda Jan 26 '17 at 9:41
  • 4
    @kusalananda, you're too good to him – J. Chomel Jan 26 '17 at 9:46
  • @J.Chomel I know. I'm a nice guy. It's a problem I have. – Kusalananda Jan 26 '17 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 – ekassis Jan 26 '17 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.