4

I want to make uppercase all driver names that are from countries starting with "United".

For example:

From

20  [United Kingdom] Nigel Mansell                 188 31

to

20  [United Kingdom] NIGEL MANSELL                 188 31

The command that I am using:

cat f1.txt | sed -r 's/[^ ]"United"\s+[A-Z]+[a-z]*]\s+[A-Z]+[a-z]*\s+[A-Z]+[a-z]*-?[A-Z]?+[a-z]?*/\U&/g'

Full list:

Rank Country         Driver                      Races Wins
1   [United Kingdom] Lewis Hamilton                264 94
3   [Spain] Fernando Alonso                        311 32
8   [United Kingdom] Jenson Button                 306 15
11  [Netherlands] Max Verstappen                   116 9
17  [United Kingdom] David Coulthard               246 13
20  [United Kingdom] Nigel Mansell                 188 31
26  [United Kingdom] Jackie Stewart                100 27
27  [United Kingdom] Damon Hill                    115 22
28  [Spain] Carlos Sainz Jr.                       115 0
32  [United Kingdom] Graham Hill                   177 14
37  [United Kingdom] Jim Clark                     72  25
38  [Poland] Robert Kubica                         97  1
41  [South Africa] Jody Scheckter                  112 10
42  [New Zealand] Denny Hulme                      112 8
47  [Switzerland] Clay Regazzoni                   131 5
49  [Sweden] Ronnie Peterson                       123 10
50  [New Zealand] Bruce McLaren                    102 4
51  [Russian Federation] Daniil Kvyat              107 0
52  [United Kingdom] Eddie Irvine                  147 4
54  [United Kingdom] Stirling Moss                 72  16
58  [United Kingdom] John Surtees                  111 6
59  [United States] Mario Andretti                 128 12
60  [United Kingdom] James Hunt                    92  10
63  [United Kingdom] John Watson                   152 5
64  [Thailand] Alexander Albon                     35  0
69  [United States] Dan Gurney                     86  4
71  [United Kingdom] Mike Hawthorn                 48  3
76  [United Kingdom] Lando Norris                  35  0
78  [United Kingdom] Paul di Resta                 59  0
80  [United States] Richie Ginther                 52  1
85  [United States] Phil Hill                      51  3
86  [United Kingdom] Martin Brundle                158 0
87  [United Kingdom] Johnny Herbert                161 3
89  [Sweden] Stefan Johansson                      79  0
90  [New Zealand] Chris Amon                       97  0
94  [United Kingdom] Tony Brooks                   41  6
95  [Venezuela] Pastor Maldonado                   95  1
99  [United Kingdom] Derek Warwick                 147 0
100 [United States] Eddie Cheever                  132 0
101 [Switzerland] Jo Siffert                       97  2
103 [Russian Federation] Vitaly Petrov             57  0
104 [United Kingdom] Peter Revson                  30  2
113 [United Kingdom] Peter Collins                 36  3
114 [United Kingdom] Innes Ireland                 52  1
119 [Sweden] Jo Bonnier                            106 1
120 [Spain] Pedro de la Rosa                       105 0
124 [United Kingdom] Mark Blundell                 61  0
125 [United States] Harry Schell                   63  0
127 [Sweden] Gunnar Nilsson                        31  1
128 [Spain] Jaime Alguersuari                      46  0
130 [United States] Jim Rathmann                   12  1
132 [United Kingdom] Mike Hailwood                 51  0
133 [Switzerland] Sebastien Buemi                  55  0
135 [United Kingdom] Mike Spence                   36  0
136 [South Africa] Tony Maggs                      26  0
140 [United States] Masten Gregory                 40  0
142 [United States] Sam Hanks                      9   1
143 [United Kingdom] Piers Courage                 27  0
145 [United States] Bill Vukovich                  5   2
147 [United Kingdom] Tom Pryce                     42  0
148 [United Kingdom] Roy Salvadori                 48  0
149 [United States] Jimmy Bryan                    9   1
153 [Sweden] Marcus Ericsson                       97  0
159 [Switzerland] Marc Surer                       82  0
160 [Netherlands] Jos Verstappen                   106 0
161 [United Kingdom] Stuart Lewis-Evans            14  0
167 [United Kingdom] Mike Parkes                   6   0
168 [United States] Rodger Ward                    12  1
174 [United Kingdom] Jonathan Palmer               84  0
176 [Sweden] Reine Wisell                          23  0
179 [United Kingdom] Jackie Oliver                 50  0
180 [United States] Johnnie Parsons                10  1
181 [United Kingdom] Peter Arundell                13  0
185 [United States] Tony Bettenhausen              13  0
186 [United Kingdom] Cliff Allison                 16  0
187 [United Kingdom] Richard Attwood               17  0
188 [United Kingdom] Peter Gethin                  30  1
191 [Switzerland] Rudi Fischer                     7   0
192 [United States] Johnny Thomson                 9   0
194 [New Zealand] Howden Ganley                    36  0
199 [United States] Troy Ruttman                   8   1
200 [United States] Lee Wallard                    2   1
1
  • Your code is trying to match sed -r '..."United"... - look at how many "s your input has around United. Repeat for everything else you're trying to match with your regexp vs whats actually present in your input.
    – Ed Morton
    Dec 28, 2020 at 23:54

3 Answers 3

8

You are overdoing it, take advantage of your file structure to keep it simple!

If we find the string [United in a line, uppercasing everything from the closing brace to the end of the line gives the result you are after. Translating this into Sed language,

sed '/\[United/s/].*/\U&/' file

Note that the above is specific to GNU Sed. If not available but in a POSIX system, you can use Ex (or see αғsнιη's Awk version) with a similar syntax:

printf '%s\n' 'g/\[United/s/].*/\U&/' '%p' | ex file

To save the changes to the file instead of printing the results, change %p to x.

0
5

Using awk:

awk -F"[][]" '$2 ~/^United/ { $2="["$2"]"; $3=toupper($3); }1' OFS='' infile

within [...] we defined both ] and [ as field separator then checking against the second field if that start with United text, if yes then add back [] around second filed (I assume there is no other column inclining these characters, else those fields will miss this); then we convert third column to its uppercase value; the idiom 1 is trigger awk default print (a kind of always true condition).

0
1

With awk we can do it by first determining the position of the closing square bracket in the current record when that record has United in its 2nd field.

$ awk '
    $2 == "[United" {
      p = match($0, /]/)
      $0 = substr($0, 1, p-1) \
        toupper(substr($0, p))
    }1
' f1.txt

Posixly sed can do it along the same lines as the awk solution. We need to get the] position and mark it so that tge pattern space is divided into two halves. Tge right half has the name and on it we uppercase it by means of the y/// command.

$ sed -e "
    /\[United[[:blank:]]/!b
   y/]/\n/
    h;s/.*\n//
    y/$(printf %s {a..z})/$(printf %s {A..Z})/
    x;s/\n.*//
    G
    y/\n/]/
" f1.txt
$ perl -pe 's/\[United\s+.*?]\K(.*)/\U$1/' f1.txt

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.