-1

I want to add filename (without extension) at the end for all the lines for all the csv files in a folder. All the files are having the same header.

Let's say I have two files a.csv and b.csv in a folder.

a.csv contains (first line is a header)

num1,num2,num3  
1,2,3

b.csv contains (first line is a header)

num1,num2,num3    
4,5,6

I want a.csv file to be (first line is a header)

num1,num2,num3,filename  
1,2,3,a

I want b.csv file to be (first line is a header)

num1,num2,num3,filename  
4,5,6,b

How can I do it in Unix?

closed as unclear what you're asking by αғsнιη, Anthon, Stephen Rauch, jimmij, Rui F Ribeiro Jul 23 '17 at 11:26

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    you want to append the filename to every line in the file? to every line except the first? to only the 2nd? – Jeff Schaller Jul 23 '17 at 1:33
  • Or do you want to change the filename based on the first (or possibly second) line in the file? – Deathgrip Jul 23 '17 at 1:37
  • Yes, I want to append the filename to every line in the file. Ideally in the first line which is a header I want to append as "filename". For all the other lines I want to append the actual file name. – Thomas Jul 23 '17 at 1:48
3
for file in *.csv
do
  filename=${file%.csv}
  sed -i -e "1s/\$/,filename/; 2,\$s/\$/,$filename/" "$file"
done
  1. Loop through every *csv file in the current directory,
  2. prepare the filename text by stripping off the trailing .csv
  3. edit the file with sed, -i in-place, by:
    1. on line 1 only, search and replace the end of the line (escaped $) with the ,filename text.
    2. on lines 2 through the end of the file ($), search and replace the end of the line ($) with a comma and the prepared filename
2

If I understood the OP correctly, then the "ideal" solution is (line 1 w/o extension, rest with extension), using GNU awk:

gawk -F, -i inplace \
'BEGIN {
    OFS=",";
 }
 {
    if(FNR==1)
        name = gensub(/^(.*)\..*/, "\\1", "g", FILENAME);
    else
        name = FILENAME;

    print $0, name;
 }' *.csv

The -F, handle and the OFS="," assignment set input and output field-separator to ,.

-i inplace means to truncate current record in the file and write current output instead into the file.

The gensub built-in saves the filename without extension in name and the print statement prints the desired modified record.

  • I have thousands of .csv files in the folder. Can we use for loop so that files can be auto picked ? – Thomas Jul 23 '17 at 1:59
  • Yes that would help – Thomas Jul 23 '17 at 2:02
  • Use *.csv instead – FloHe Jul 23 '17 at 2:10
  • @AFSHIN: I don't think so. He said: "Ideally in the first line which is a header I want to append as "filename". For all the other lines I want to append the actual file name" , which imho is consistent with my interpretation. – FloHe Jul 23 '17 at 3:14
  • oops, OP's comment is completely different with his question's body, deleted my comment – αғsнιη Jul 23 '17 at 3:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.