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
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Thiyagu
  • 111
  • 3

3 Answers3

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)
Archemar
  • 31,183
  • 18
  • 69
  • 104
-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.

rahul
  • 1,181
  • 7
  • 19
  • Edit, as @jasonwryan pointed out in your previous post, you do not even need the {print $0}. – rahul Mar 05 '15 at 08:20
  • 2
    There is no point in using `ls` here. You can just say `for file in A_*.csv`. – camh Mar 05 '15 at 08: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 05 '15 at 09: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 05 '15 at 09:26
  • @rahul The files are in the same directory. I used append (>>). I don't know why it shows only one row. – Thiyagu Mar 05 '15 at 09:33
  • @rahul it just takes the header of the first file. The rest its not appending. – Thiyagu Mar 05 '15 at 09:41
  • @Thiyagu can you paste the code and listing contents of the directory here? Maybe there is a typo somewhere. – rahul Mar 05 '15 at 09:53
  • @rahul Kindly look in the code under the subheading "UPDATED CODE ". – Thiyagu Mar 05 '15 at 10:04
  • Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/21669/discussion-between-rahul-and-thiyagu). – rahul Mar 05 '15 at 10:12
  • @Thiyagu I'm having some problems logging into chat, but i figured out the problem. Please remove the ''. Instead of for file in 'A_*.CSV', use for file in A_*.CSV . – rahul Mar 05 '15 at 10:17
  • great. It works fine. Why is that so. What difference it makes ? – Thiyagu Mar 05 '15 at 10:20
  • http://mywiki.wooledge.org/ParsingLs – Gilles 'SO- stop being evil' Mar 05 '15 at 22:32
-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.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175