dig_123
dig_123

Reputation: 2368

Change only single occurence of space inbetween characters in bash

I've an output as below:

NAME                UUID                                  TYPE            DEVICE 
Wired connection 1  e4249ef0-c4f0-3b64-8950-0c6be3edaca5  802-3-ethernet  enp0s3 

I want to pick the device name if the type has wireless mentioned in it, using awk.

Expected output:
enp0s3

However one problem though. The NAME sometimes can be a single word in which case awk can recognize the TYPE and DEVICE as field 3 & 4.

awk '$3 ~ /wireless/{ print $4 }'

But The NAME sometimes has spaces in between, which I want to deal with first before applying awk, else its behaving erratically. if I can change the single spaces into "-", it solves my purpose.

Suggestions please.

Upvotes: 0

Views: 62

Answers (3)

James Brown
James Brown

Reputation: 37414

First better test data (ie. with a match):

$ cat file
NAME                UUID                                  TYPE            DEVICE 
Wired connection 1  e4249ef0-c4f0-3b64-8950-0c6be3edaca5  802-3-ethernet  enp0s3 
Wireless conn       e4249ef0-c4f0-3b64-8950-0c6be3edaca5  802-3-wireless  enp0s3 

Then, A GNU awk script based on @EdMorton's script for dealing with fixed width data (which I seem to need to use a lot, too bad I can't give it more ++, here):

awk '
FNR==1 {
    FIELDWIDTHS=""
    while ( match($0,/\S+\s*/) ) {
        FIELDWIDTHS = (FIELDWIDTHS ? FIELDWIDTHS " " : "") RLENGTH
        $0 = substr($0,RSTART+RLENGTH)
    }
    next
}
$3~/wireless/ { print $4 }
' file
Wireless conn

Edited to print $4 instead of $1 as OP clarified the question.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203712

You said you want to print the "device name" so we don't know if you want to print the "DEVICE" field or the "NAME" field so we're all just guessing. That's why it's important to include the expected output in any question.

To print the DEVICE field:

awk '$(NF-1) ~ /wireless/ { print $NF }' file

To print the NAME field:

awk '$(NF-1) ~ /wireless/ { sub(/([[:space:]]+[^[:space:]]+){3}[[:space:]]*$/,""); print }' file

It'll work no matter what white space your file contains between fields as long as only the NAME field can itself contain white space.

Upvotes: 4

Tom Fenech
Tom Fenech

Reputation: 74675

You can use the first line to measure the start and end of the third field and then search that range of characters in subsequent lines for the pattern(s) you're interested in:

awk 'NR == 1 { start = index($0, $3); end = index($0, $4); next }
     substr($0, start, end - start) ~ /less/ { print $NF }' file

Upvotes: 1

Related Questions