0

I have a set of csv files, and for each file, the first line contain field names for a data set. Some csv files have all upper case for the field names, others have all lower case for the field names. My question is how do I change every csv file so that the first line of each file (aka the field names) displays as all uppercase strings in each column?

Examples: Dataset1.csv

a b c
x x x

Dataset2.csv

A B C
y y y

How do I make Dataset1.csv look like the following?

A B C
x x x
3

It may be done with the option to Uppercase of GNU sed. In-place with the option -i:

sed -i '1s/.*/\U&/' Dataset1.csv
1

We can do by using awk and GNU sed

Method1

awk 'NR==1{(i=toupper($0));print i}' Dataset1.csv ; awk 'NR >=2 {print $0}' Dataset1.csv

Output

A B C
x x x
z z z

Method 2

sed '1s/.*/\U&/g' Dataset1.csv

Output

A B C
x x x
z z z
  • 1
    awk 'NR==1{print toupper($0)}NR>1' for a simplification and a single pass through the file – Fox Feb 9 '18 at 6:39
  • 1
    @Praveen, when someone takes the time to suggest an improvement to your answer, it’s nice to thank them, but it’s nicer still to actually improve your answer accordingly. If you like code golf, awk 'NR==1{$0=toupper($0)}1' is shorter still ;-). – Stephen Kitt Feb 9 '18 at 9:15
  • 1
    Let me just qualify the above, obviously you needn’t change your answer if you disagree with the improvement! – Stephen Kitt Feb 9 '18 at 9:24
  • @StephenKitt Thanks for input . Answer which you provided is more efficient than mine – Praveen Kumar BS Feb 10 '18 at 9:19
0

This is a repost from stackoverflow since someone told me my question was off-topic for the site and I got the following answers:

Considering your file ends with a newline:

head -1 Dataset1.csv | tr '[:lower:]' '[:upper:]' > Dataset1_new.csv ; tail -$(( $(wc -l Dataset1.csv | cut -d ' ' -f 8) - 1 )) Dataset1.csv > Dataset1_new.csv

head -1 Dataset1.csv | tr '[:lower:]' '[:upper:]': takes the first line of your file, transforms it to uppercase & outputs it on stdout

> Dataset1_new.csv: redirects the output to a new file called Dataset1_new.csv

tail -$(( $(wc -l Dataset1.csv | cut -d ' ' -f 8) - 1 )) Dataset1.csv: outputs the rest of the lines

> Dataset1_new.csv: again, redirects the output to our Dataset1_new.csv file

You can do it with GNU sed:

$ sed -i -e '1 s/\(.*\)/\U\1/' input.csv

You can also use awk for this purpose:

awk -i.bak 'NR==1{ print toupper($0) }NR>1' Dataset1.csv

Explanations:

awk will take a backup of your csv file and then for the first line (NR==1) will change the whole line $0 to uppercase then for the rest of the file (NR>1) will do its default action which is printing the line.

  • first method is too complex, yet I see no reason to dwonvote. – Archemar Feb 9 '18 at 6:28
  • Yea sorry I should have commented. I downvoted because as op says it's a repost from stack overflow and I'm sure this question has been answered on here before as well. – Jesse_b Feb 9 '18 at 12:49
  • The head/tail solution can be simplified to { head -1 | tr '[:lower:]' '[:upper:]'; cat; } < file > file.new – glenn jackman Feb 9 '18 at 17:31
  • and note that if you use wc with data from stdin, you don't need to cut -- lines=$(wc -l < file) – glenn jackman Feb 9 '18 at 17:33

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.