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 

3 Answers 3

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.

12
  • Edit, as @jasonwryan pointed out in your previous post, you do not even need the {print $0}. Commented Mar 5, 2015 at 8:20
  • 2
    There is no point in using ls here. You can just say for file in A_*.csv. Commented Mar 5, 2015 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). Commented Mar 5, 2015 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. Commented Mar 5, 2015 at 9:26
  • @rahul The files are in the same directory. I used append (>>). I don't know why it shows only one row. Commented Mar 5, 2015 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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.