7

I have a text file like this:

1 http http 3 4 5 
2 dns dns 4 
3 ftp ftp 4 5 6 8 

I want the output to be like this:

1 HTTP http 3 4 5 
2 DNS dns 4 
3 FTP ftp 4 5 6 8 

I want to change the second field from lower-case into upper-case and only the second field.

Note that the number of fields in a certain line is not fixed.

Can I accomplish this goal using awk?

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
Yishu Fang
  • 9,448
  • 21
  • 65
  • 102

2 Answers2

14

You sure can. Here's how:

awk '$2 = toupper($2)' file

Results:

1 HTTP http 3 4 5
2 DNS dns 4
3 FTP ftp 4 5 6 8

From the manual:

tolower(str)

Returns a copy of the string str, with all the upper-case characters in str translated to their corresponding lower-case counterparts. Non-alphabetic characters are left unchanged.

toupper(str)

Returns a copy of the string str, with all the lower-case characters in str translated to their corresponding upper-case counterparts. Non-alphabetic characters are left unchanged.


I made the assumption that given your sample data, it would have at least three columns and that the variable component you discuss applies to the columns after those containing words. If I was wrong, you can simply add the conditional:

awk 'NF>1 { $2 = toupper($2) }1' file
Steve
  • 51,466
  • 13
  • 89
  • 103
  • 1
    Be careful: this will delete lines with only one field . Perhaps `awk '($2 = toupper($2)) || 1' file` – William Pursell Dec 24 '12 at 16:51
  • This breaks on a line which has less than 2 fields. In this case, the line is not printed as `$2` evaluate to the empty string. I would be careful using an assignment where awk expects a test. It also breaks if you do `awk -F "[ ]" '$2 = toupper($2)' <<< "a b c"` where the 2nd field is the empty sting. It can easily be fixed doing `awk 'NF > 1{$2 = toupper($2)} 1' file`. – jfg956 Dec 24 '12 at 16:51
  • @WilliamPursell: your solution adds an ending space on lines with a single field. – jfg956 Dec 24 '12 at 16:53
0
perl -F -ane '$F[1] = lc($F[1]);print "@F"' your_file
Vijay
  • 65,327
  • 90
  • 227
  • 319