1

my intention is to keep the code as simple as possible.Here there are 5 files namely

A_1.CSV, A_2.CSV, A_3.CSV, A_4.CSV, A_5.CSV

The below code retrieves the first row in a CSV file.

Code : head.sh(filename)

awk -F, 'NR==1 {print $0}' A_1.CSV > Header.csv
awk -F, 'NR==1 {print $0}' A_2.CSV >> Header.csv
awk -F, 'NR==1 {print $0}' A_3.CSV >> Header.csv
awk -F, 'NR==1 {print $0}' A_4.CSV >> Header.csv
awk -F, 'NR==1 {print $0}' A_5.CSV >> Header.csv

Question :

In the above code, only the filename changes from A_1 to A_2 and so on. How can I make the code simple with loops.

Example :

 for (i=1;i<=5;i++)
      {
       A_[i].CSV >> Header.csv
      }

I don't know how to do this logic with shell scripting.

UPDATED CODE :

Files in the Directory : /home/thiyagu/Desktop/

for file in 'A_*.CSV'
do
awk -F, 'NR==1 {print $0}' $file >> Newheader.csv
done
1

what about

 awk 'FNR==1' A_*.csv > Header.csv

where

  • FNR is File Number Record
  • default action is to print the while line
  • I dropped -F, as you don't care about individual field (If you have other thing to do, however, you can add it back)
-1

Something like this will work:

for file in `ls A_*.csv`
do
awk -F, 'NR==1 {print $0}' $file >> Header.csv
done

This is basic shell scripting looping. You can find these tutorials online, if you search for them.

  • Edit, as @jasonwryan pointed out in your previous post, you do not even need the {print $0}. – rahul Mar 5 '15 at 8:20
  • 2
    There is no point in using ls here. You can just say for file in A_*.csv. – camh Mar 5 '15 at 8:53
  • @camh @rahul yup ls is not needed. I am getting the result just for one file. In the Header.csv, I can find only one row. But, I need it for multiple files(i.e 5 rows). – Thiyagu Mar 5 '15 at 9:17
  • @Thiyagu are you sure you are pointing to the correct files? I tested this for two files (A_1.csv, A_2.csv) and it extracted the header from both the files and placed them in Header.csv. Are your source files in different directories? Or did you use '>' instead of '>>' . The first will overwrite and the second will append. – rahul Mar 5 '15 at 9:26
  • @rahul The files are in the same directory. I used append (>>). I don't know why it shows only one row. – Thiyagu Mar 5 '15 at 9:33
-1

Single quotes prevent expansion: every character in a single-quoted string is interpreted literally (except ' itself which ends the string). So when you want * to act as a wildcard, leave it outside the quotes. (Double quotes also prevent * from acting as a wildcard.)

for file in A_*.CSV …

The rest of your updated code is probably ok, but you should put double quotes around variable substitutions, otherwise sooner or later it will bite you.

You can take the redirection outside the loop. This is slightly faster.

for file in A_*.CSV
do
  awk -F, 'NR==1 {print $0}' "$file"
done >> Newheader.csv

This snippet appends to Newheader.csv. If you want to overwrite the file when it already exists, like in your original code, replace >> by >.

There are several ways to simplify your script, if all you want is to print the first line of several files. Since you're just printing the first line, -F, isn't used. Furthermore you could use head -n 1 instead of awk 'NR == 1 {print $0}'. On Linux (but not on all Unix variants), to print just the first line of several files, you can use head without any loop:

head -q -n 1 A_*.CSV >Newheader.csv

You also don't need a loop with awk, see Archemar's answer.

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.