user1835630
user1835630

Reputation: 261

converting string to lower case part of a string in bash shell scripting

I have a file.txt and each line of the file is like:

ABLED   EY B AH L D
ABLER   EY B AH L ER

I want to have the second part of each line: EY B AH L D or EY B AH L ER, for example, in lower case, keeping the rest upper case. How can I do it?

Thank you very much in advance.

Upvotes: 4

Views: 4006

Answers (6)

user2269995
user2269995

Reputation: 1

Please use #!/bin/ksh in the begining of the script even if you want it to run it in Linux platform. This ksh accepts all kind of typeset variables that we use in HpUx or Solaris.

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361537

while read first second; do
    second=$(echo "$second" | tr [:upper:] [:lower:])
    printf '%s\t%s\n' "$first" "$second"
done < file.txt

Output:

ABLED   ey b ah l d
ABLER   ey b ah l er

Two other ways to do it in KornShell, pdksh, or Bash without calling tr

set the "lowercase" flag on the variable (KornShell and compatible shells only):

typeset -l second
while read first second; do
    printf '%s\t%s\n' "$first" "$second"
done < file.txt

use Bash's case-modification parameter expansion modifier (Bash only!):

while read first second; do
    printf '%s\t%s\n' "$first" "${second,,}"
done < file.txt

Upvotes: 8

jfg956
jfg956

Reputation: 16730

It can be done with sed using the following incredibly obfuscated script:

sed -e 'h;s/ .*//;x;s/[^ ]* //;y/AZERTYUIOPQSDFGHJKLMWXCVBN/azertyuiopqsdfghjklmwxcvbn/;H;x;s/\n/ /' your_file

Explained:

The first part of the script (h;s/ .*//;x;s/[^ ]* //) puts the part a the line before the 1st space in the hold space and the part of the line after the 1st space in the pattern space:

  • h: copies the actual line in the hold space.
  • s/ .*//: keeps in the pattern space only characters before the 1st space.
  • x: switch hold and pattern space.
  • s/[^ ]* //: keeps in the pattern space only characters after the 1st space.

Ok, now we have the 1st part of the line in the hold space, and the 2nd in the pattern space. We need to put the 2nd part in lower case, so we use y/AZERTYUIOPQSDFGHJKLMWXCVBN/azertyuiopqsdfghjklmwxcvbn/ (yes, I have an AZERTY keyboard).

Then, it is only a matter of getting back the 1st and 2nd part of the files together:

  • H: append pattern space to hold space.
  • x: exchange pattern space and hold space.
  • s/\n/ /: replace the \n of the H command by a space.

I hope you are not to disgusted by sed synthax ;-).

Upvotes: 1

jfg956
jfg956

Reputation: 16730

If you want a solution working with pipes (not the paste solution) and easier to understand than the sed solution, this is a solution with awk:

awk -F "[ ]" '{str=$1;$1="";print str tolower($0)}' your_file

The field separator cannot simply be " " as consecutive spaces are in this case considered as a single separator.

Upvotes: 0

jfg956
jfg956

Reputation: 16730

If you know your file will not change while reading it, and using bash:

paste -d " " <(cut -d " " -f 1 your_file) <(cut -d " " -f 2- your_file | tr "[:upper:]" "[:lower:]")

Upvotes: 0

piokuc
piokuc

Reputation: 26164

A Python script:

import sys
for l in sys.stdin.read().splitlines():
    try:
        head,rest = l.split(' ', 1)
        print head, rest.lower()
    except: print l

Run it like this (assuming you save the script in a file called filter.py):

$ python filter.py < file.txt

Upvotes: -1

Related Questions