Alaa Yalda
Alaa Yalda

Reputation: 51

Resort a Row of textfile

computer0-1   computer0-2   computer0-3
computer0-10  computer0-5   computer0-6
computer0-2   computer0-7   computer0-3

These saved in a text file. I want to write a bash script that will check the every line:

I tried to use if and for loop but I don't know how to write them I righ set.

I need to write a script to do this and I'm new in Linux. How can I do this? Is there an easy way to do it?

Upvotes: 1

Views: 85

Answers (2)

Aaron
Aaron

Reputation: 24812

With sed :

sed -e 's/^.*\b\(computer0-1\)\b/\1\t\0/' -e 's/^.*\b\(computer0-10\)\b/\1\t\0/' -e 's/^.*\b\(computer0-7\)\b/\1\t\0/' <file>

It searches for one of the computer0-1, computer0-10, computer0-7 in the line and if found places a copy of it at the beginning of the line, followed by a tabulation and the rest of the line.

Detailed explanation :

s/<search>/<replace>/ replaces the <search>ed pattern with the <replace> expression
^ matches the start of the line
.* matches everything until the next pattern matches
\b is the word-boundary metacharacter : it matches the start and end of a word of [a-zA-Z_] characters
\(...\) groups a fragment of pattern. We can reference it later.
\1 is a back-reference to the first (and only) group defined earlier
\0 is a back-reference to the whole matched string

So what we did is match up to the searched token (i.e. computer0-1) while making sure it's a whole word (computer0-1 shouldn't match computer0-12), then we recreate the matched string by appending it to the matched token.

Test run :

$ echo """computer0-1   computer0-2   computer0-3
> computer0-10  computer0-5   computer0-6
> computer0-2   computer0-7   computer0-3""" > input

$ sed -e 's/^.*\b\(computer0-1\)\b/\1\t\0/' -e 's/^.*\b\(computer0-10\)\b/\1\t\0/' -e 's/^.*\b\(computer0-7\)\b/\1\t\0/' input
computer0-1     computer0-1   computer0-2   computer0-3
computer0-10    computer0-10  computer0-5   computer0-6
computer0-7     computer0-2   computer0-7   computer0-3

Upvotes: 2

karakfa
karakfa

Reputation: 67507

awk to the rescue!

$ awk '{for(i=1;i<=NF;i++) if($i~/computer0-(1|10|7)$/) print $i, $0}' file | column -t

computer0-1   computer0-1   computer0-2  computer0-3
computer0-10  computer0-10  computer0-5  computer0-6
computer0-7   computer0-2   computer0-7  computer0-3

Note that this search is by field order and first match will be printed. If the priority of the keys is important (in case of -1 and -10 match on the same line always use -1) you can use this

$ awk 'BEGIN{pre="computer0-"; p[1]=pre"1 "; p[2]=pre"10"; p[3]=pre"7"}
            {for(i=1;i<4;i++) 
               if($0~p[i]) 
                  {print p[i], $0; 
                   next}
            }' file | column -t

Upvotes: 1

Related Questions