I have a file structured like this:

[IP ADRESS], [ID-Number], [Name]
[IP ADRESS], [ID-Number], [Name]
[IP ADRESS], [ID-Number], [Name]

(The actual values are not in brackets)

How do I get (print) a specific value (either IP-Adress, ID or Name) while looping through the lines (preferably with 'sed' since I already started looking into that)?

My objective is to send an SSH command to each server by grabbing the IP Address with a script, and then having the ID Number and Name for another program which displays the output of each command in combination with the name (I'm trying to build a monitoring service for our servers). So I need to be able to only grab one or two of those values.


awk is probably the most straight-forward tool for this job.

It appears from your sample input file (call it foo) that each field except the last one on a line has a comma and then a space after it.

So to print the IP address from each line, use:

$ awk -F', ' '{print $1}' < foo

To print the ID number from each line, use:

$ awk -F', ' '{print $2}' < foo

To print the name from each line, use:

$ awk -F', ' '{print $3}' < foo

It is also possible to craft a single awk statement which creates output that combines the various input fields:

$ awk -F', ' '{print "ssh " $1 " /path/to/myscript.sh " $2 " " $3}' < foo

Once you have reviewed the output from that statement to ensure that it is accurate and effective for your purposes, you can easily execute it by piping it into a shell:

$ awk -F', ' '{print "ssh " $1 " /path/to/myscript.sh " $2 " " $3}' < foo | bash

Adding an answer based on your recent update (SSH into each server, and run one or more commands that use the ID & Name values).

Starting with an example file like this:

$ cat testfile.txt,12345,N1,23456,N2,34567,N3

A while loop with read can do the job:

while IFS=, read -r IP ID NAME; do 
    echo "ssh $IP myprogram $ID $NAME"
done < testfile.txt

Which gives you the following output:

ssh myprogram 12345 N1
ssh myprogram 23456 N2
ssh myprogram 34567 N3

The loop works in the following manner. From the input file, each line is read in turn. On each line, the contents are split into different fields based on the special IFS variable. By setting IFS=, you split the line on each occurrence of the ',' character. This will result in each line being split into three fields.

Once that's done, each field is assigned to the corresponding variables IP, ID & NAME. These variables are available to you inside the body of the loop. As an example, I am simply printing out a possible ssh command for each line.

Note that the CSV file I have used as an example is a simple one. If you have a more complex CSV file, you will need to look at using a proper CSV parser such as csvkit.


Using Miller (https://github.com/johnkerl/miller/releases/tag/5.4.0), starting from,8695458,Malcolm,7589632,Jerry,4571286,Basil

If you want the rows in which the second field is equal to 7589632

mlr --nidx --fs "," filter -S '$2=="7589632"' input.csv

If you want only the first column of the rows in which the second field is equal to 7589632

mlr --nidx --fs "," filter -S '$2=="7589632"' then cut -f 1 input.csv

A "perl" one-liner would be a good potential solution.

Since you haven't provided us with a sample of your data, i can only guess that it will look somewhat like this.

  •, 8695458, Malcolm
  •, 7589632, Jerry
  •, 4571286, Basil

In such a case you could run the following line.

perl -lne '/(\b\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}\b), (\b\d{1,10}\b), (\b\w+\b)/ && print $1' input_file

Change the number in "Print $1" for "2" or "3" to print only the "ID" or "NAME", respectively.


I like Haxiel's solution and add something....

  while IFS=, read -r IP ID NAME; do 
      echo "ssh $IP myprogram $ID $NAME"
  done << ENDEND,12345,N1,23456,N2,34567,N3

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.