Velvet Star Monitor

Standout celebrity highlights with iconic style.

updates

Lowercase all but the first column

Writer Matthew Barrera

How can I make all but the first column lower case?

like:

1 ONE
2 TWO TWO
3 THREE THREE THREE

required output:

1 one
2 two two
3 three three three
4

4 Answers

You could use GNU sed's lowercase \L extension:

sed -r 's/([^ \t]+\s)(.*)/\1\L\2/' file

Explanation

  • -r use ERE
  • s/old/new/ replace old with new
  • ([^ \t]+\s) save some characters that are not space or tab, followed by a space or tab
  • (.*) save any number of any characters
  • \1\L\2 print the first saved part unchanged, then the second saved part lowercased

awk with iterating over all but the first field, and converting the strings to lowercase using tolower() function:

awk '{out=""; for (i=2; i<=NF; i++) out=out" "tolower($i); print $1out}' file.txt

paste, cut, and sed, with help from process substitution:

paste -d ' ' <(cut -d' ' -f1 file.txt) <(cut -d' ' -f2- file.txt | \ sed -E 's/([[:upper:]])/\L\1/g')

This has the caveat of opening the file twice.


With only bash, using parameter expansion to convert cases:

while IFS=' ' read -r i j; do echo "${i} ${j,,}"; done <file.txt

Example:

$ cat file.txt
1 ONE
2 TWO TWO
3 THREE THREE THREE
$ awk '{out=""; for (i=2; i<=NF; i++) out=out" "tolower($i); print $1out}' file.txt
1 one
2 two two
3 three three three
$ paste -d ' ' <(cut -d' ' -f1 file.txt) <(cut -d' ' -f2- file.txt | sed -E 's/([[:upper:]])/\L\1/g')
1 one
2 two two
3 three three three
$ while IFS=' ' read -r i j; do echo "${i} ${j,,}"; done <file.txt
1 one
2 two two
3 three three three
3

Perl approach with the use of lc() function:

$ perl -lne 'print lc($_)' < input.txt
1 one
2 two two
3 three three three

Python approach:

$ python -c "import sys;print ''.join([l.lower() for l in sys.stdin])" < input.txt
1 one
2 two two
3 three three three
  • send input file as stdin to the python command using < shell redirection
  • using sys read all lines using list comprehension (the l for l in list structure), while simultaneously using .lower() method
  • the resulting list of lines is joined into one string and printed out

If you want to remove trailing newline, you can do so by adding single comma at the end for Python 2 (which is default for python command ):

$ python -c "import sys;print ''.join([l.lower() for l in sys.stdin])," < input.txt

For Python 3, the print function is different, and it has different way of stripping trailing newline - via end keyword:

$ python3 -c "import sys;print(''.join([l.lower() for l in sys.stdin]),end='')" < input.txt 

Previous approaches assume that first column is numeric as in OP's example. For generic approach where we want only non-first columns to be converted, we can do this in perl:

$ cat input.txt
1 ONE
SOMETHING TWO TWO
$!@# THREE THREE THREE
$ perl -ane 'print $F[0]; print map { " " . lc($_)} @F[1..$#F];print "\n"' < input.txt
1 one
SOMETHING two two
$!@# three three three

In python for the sake of readability, we can do a script:

#!/usr/bin/env python
import sys
for line in sys.stdin: words = line.strip().split() case_words = [ word.lower() for word in words[1:] ] print( " ".join([words[0]]+case_words) )

Which works like so with the same input as in perl example:

$ ./lowercase_columns.py < input.txt
1 one
SOMETHING two two
$!@# three three three
4

A late one:

Just for fun, another python approach:

python3 -c "for l in open('f'): l = l.split(' ',1); print(l[0], l[1].strip().lower())"

Where 'f' is the file, between quotes.

This approach assumes the file does not have empty lines.

Explanation

  • Each of the lines is first split on the first occurrence of the delimiter.

    l = l.split(' ',1)
  • Subsequently, the second part (all columns but the first) is lowered:

    l[1].strip().lower()
  • and the combined result is printed:

    print(l[0], l[1].strip().lower())

Example output

On a file:

EEN AAP OP EEN FIETS
2 EEn banaan IS LEKKER
MIJN tante in Marokko
1 ONE
2 TWO TWO
3 THREE THREE THREE

The output is:

EEN aap op een fiets
2 een banaan is lekker
MIJN tante in marokko
1 one
2 two two
3 three three three

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy