Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question
    
What have you tried by yourself ? – J. Chomel 14 hours ago
up vote 7 down vote accepted

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
share|improve this answer
    
I need the solution in one command line and not a script please – ekassis 14 hours ago
    
@ekassis Sorted. – Kusalananda 14 hours ago
4  
@kusalananda, you're too good to him – J. Chomel 14 hours ago
    
@J.Chomel I know. I'm a nice guy. It's a problem I have. – Kusalananda 14 hours ago
    
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 14 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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