3

I have a csv file that looks like below

"10.8.70.67","wireless",,"UTY_07_ISD",,26579
"10.8.70.69","wireless",,"RGB_34_FTR",,19780

I want to retrieve first, second and fourth column values (without quotes) and populate into a another csv in the below format.

IP          DEVICETYPE  DEVICENAME
10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR

I have used the below awk command

awk -F ',|,,' '{gsub(/"/,"",$1); gsub(/"/,"",$2); gsub(/"/,"",$3); print $1, $2, $3}' file.csv

and got the below output

10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR

please help in assigning headings to each column.

8
  • 1
    @tink, IMHO, this doesn't look like a dupe for this question. Commented Feb 16, 2021 at 8:09
  • 1
    Your desired output is not CSV at all. Please clarify; do you actually want an answer for CSV (in which case the duplicate is correct) or for fixed-width space-separated columns? Commented Feb 16, 2021 at 8:15
  • 2
    Hi, I am able to get the required output. I just want to add heading to each column. OP has given this comment in my answer's section by which I am thinking that OP may not needed a csv file in output but lets wait for OP to come back here, though I will still say it was too early to make this dupe, once OP confirms about it and dupe link is working fine for him then its certainly a dupe. Commented Feb 16, 2021 at 8:46
  • 2
    I have re-opened the question, by seeing OP's comments on answer section Hi, I am able to get the required output. I just want to add heading to each column.(for which it doesn't look like correct dupe) if in case OP confirms on tripleee's above comments then will vote to make it dupe, thank you. Commented Feb 16, 2021 at 9:40
  • 1
    @tink, Hello tink, I could see stackoverflow.com/questions/37216107/… this link from history which is completely different from which you are sharing now. So I have checked this link. Also OP's approach towards solving this problem doesn't look good here, so approaches given here will help to make that part efficient also along with only adding headers IMHO. Commented Feb 16, 2021 at 16:51

4 Answers 4

7

assuming you don't have comma or double quotes in the quoted strings (a big assumption!) it can be as simple as

$ awk -F, 'NR==1 {print "IP","DEVICETYPE","DEVICENAME"} 
                 {gsub(/"/,""); 
                  print $1,$2,$4}' file | column -t

IP          DEVICETYPE  DEVICENAME
10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR
Sign up to request clarification or add additional context in comments.

2 Comments

I got the output with the command awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub(/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv I found that I was missing BEGIN part. Thanks for your response.
@selvanvenkatesh Note that BEGIN will print the header even if the input file is empty. The other alternative will only add header if there is at least one line in the input file.
1

With your shown samples, could you please try following. Written and tested in GNU awk.

awk -v FPAT='([^,]*)|("[^"]+")' '
BEGIN{
  OFS=","
  print "IP          DEVICETYPE  DEVICENAME"
}
function remove(fields){
  num=split(fields,arr,",")
  for(i=1;i<=num;i++){
    gsub(/^"|"$/,"",$arr[i])
  }
}
{
  remove("1,2,4")
  print $1,$2,$4
}
' Input_file

Explanation: Adding detailed explanation for above.

awk -v FPAT='([^,]*)|("[^"]+")' '    ##Setting FPAT to get only matched fields only as ([^,]*)|("[^"]+") as per samples.
BEGIN{                               ##Starting BEGIN section of this program from here.
  print "IP          DEVICETYPE  DEVICENAME" ##printing header here.
}
function remove(fields){             ##Creating function named remove here where we are passing field numbers from where we need to remove "
  num=split(fields,arr,",")          ##Splitting fields into arr here.
  for(i=1;i<=num;i++){               ##Traversing through all items of arr here.
    gsub(/^"|"$/,"",$arr[i])         ##Globally substituting starting and ending " in mentioned fields with NULL here.
  }
}
{
  remove("1,2,4")                    ##Calling remove here with field numbers of 1,2 and 4 which we need as per output.
  print $1,$2,$4                     ##Printing 1st, 2nd and 4th field here.
}
' Input_file                         ##Mentioning Input_file name here.

6 Comments

Hi, I am able to get the required output. I just want to add heading to each column.
@selvanvenkatesh, sure, I have edited my code now, kindly check it once and let me know how it goes? cheers.
@selvanvenkatesh, could you please reply on tripleee's comment in question section(where its being asked if you need a csv file or not in output) and confirm if attached link for duplicate question helping you or not, thank you.
I got the output with the command awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub(/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv I found that I was missing BEGIN part. Thanks Ravinder for your response.
@selvanvenkatesh, you didn't answer my previous comment, do you need commas in your expected output? Because your samples of output doesn't show that? Kindly do confirm on same once.
|
0

A simple oneliner will be:

awk -F ',|,,' 'BEGIN {format = "%-20s %-20s %-20s\n"; printf format, "IP", "DEVICETYPE", "DEVICENAME"} {gsub(/"/,"",$1); gsub(/"/,"",$2); gsub(/"/,"",$3); printf format, $1, $2, $3}' abc.csv

Here I have used BEGIN/END special pattern, which is used to do some startup or cleanup actionn, to add headings. For more details please refer to the documentation Using BEGIN/END

1 Comment

I got the output with the command awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub(/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv I found that I was missing BEGIN part. Thanks for your response.
-2

I got the expected output with the below command

awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub(/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv

I found that I was missing BEGIN part. Thanks all for your response.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.