Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

We will generate a csv file with below values

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

I need to extract data and create files based on second column. If it's 577 then the whole line has to be extracted and placed in a separate file. I mean I need a file having lines with second column as 577 alone and another file with second column as 132 alone

I tried using IF but didn't work

share|improve this question
2  
Actually posting the code that doesn't work is always a good idea. –  goldilocks Feb 7 at 16:38
add comment

3 Answers 3

Use awk:

awk -F, '{print >$2".csv"}' file.csv

This will create the two files 577.csv and 132.csv in your current directory.

The command above assumes that you can only have 132 or 577 as the second field. It will create one file name for each of the values found in the second field of the entire file.csv. If there are other options apart from the tow you are interested in, and you want to ignore those lines, do this instead:

awk -F, '$2=="577" || $2=="132"{print >$2".csv"}' file.csv
share|improve this answer
    
+1 for elegant and terse awk –  grebneke Feb 7 at 17:25
    
@StephaneChazelas thanks, the comma I should have seen but the > is a surprise. So awk keeps the file handle open for writing until it finishes? I had thought that it opens it on each line so the >> would be necessary. Anyway, thanks, answer edited. –  terdon Feb 7 at 17:29
1  
Note that $2==577 does a numeric comparison, while $2".csv" will use the second field as a string. So if there's a line with 0577 and one with 577 they will both be included, but one in a 0577.csv and the other in 577.csv. You may want to either write $2 == "577" or print > +$2 ".csv" for consistency. –  Stéphane Chazelas Feb 7 at 17:34
    
@StephaneChazelas good point, I had not considered 0577, thanks. –  terdon Feb 7 at 17:35
    
Are the () around comparisons necessary? $2=="577" || $2=="132" should be enough, no? –  grebneke Feb 7 at 17:43
show 1 more comment

I like terdon's awk solution, but for the sake of completeness, here is a suggestion using only bash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

It will produce files 577.csv and 132.csv in the current directory.

share|improve this answer
    
this worked well.... thanks.. –  user3116123 Feb 11 at 15:57
add comment

To extract all 577 to stdout

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

-- edit 1 Corrected, based on @terdon's comment below to avoid false matches when at least 3 commas on line with 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

But I think his/her awk solution is more comprehensive.

share|improve this answer
    
That will match even if 577 is on another field, not the second or if it is a part of a field. For example foo577bar or yp9012,132,8,577. –  terdon Feb 7 at 16:50
    
I thought my commas would make it field position dependent ? –  X Tian Feb 7 at 16:58
    
Sorry, I gave bad examples but the .* can also match commas so you don't know which field you're matching. Could be the second, could also be the 45th. My second complaint was wrong, you're right that the commas protect from matching foo577bar. –  terdon Feb 7 at 17:01
    
what to do if | character is used instead of , . –  user3116123 Feb 11 at 15:41
    
receiving below error grep: illegal option -- e Usage: grep -hblcnsviw pattern file . . . –  user3116123 Feb 11 at 15:44
show 1 more comment

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.