Sandra Schlichting
Sandra Schlichting

Reputation: 25986

How to lower case part of file with awk?

I have a lot of files, which contain lines such as

local1 = "AAA"
private = "Filename_With_Uppercase"

where I would like to change the right side of the equal side to only lower case. But only for lines that start with private.

If I do

gawk -F'=' '/^private/{gsub(/[-/]/, "_"); tolower($2)} 1' filename

then it doesn't change anything...

Question

Can anyone figure out why the right hand side of the equal side isn't converted to lower case?

Upvotes: 2

Views: 717

Answers (4)

anubhava
anubhava

Reputation: 785126

Since you're already using gnu awk, it can be done in a single step in gensub function:

awk -F= '/^private/ {$2 = gensub(/[-/]/, "_", "g", tolower($2))} 1' file

local1 = "AAA"
private   "filename_with_uppercase"

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133508

With your shown samples, please try following awk code.

awk -F'^private = ' 'BEGIN{OFS="private = "} NF>=2{$2=tolower($2)} 1' Input_file

Explanation: Simple explanation would be, making ^private = as a field separator for all lines here. Then setting OFS to private = for all lines. In main program checking if number of fields are more or equal to 2 then changing whole 2nd field to lower case as per requirement and printing the edited/non-edited lines then.

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 203502

You have to actually use the value returned by tolower(), it's not like [g]sub() where it modifies it's argument it's more like substr() in that it returns the modified string, see the awk manual.

Any solution that is working with $2 or otherwise relies on fields being split on = will fail when your file names contain = signs. This is how to work with tag=value pairs of input data:

$ cat tst.awk
{
    tag = val = $0
    sub(/ *=.*/,"",tag)
}
tag == "private" {
    sub(/[^=]+ *= */,"",val)
    gsub(/[-/]/,"_",val)
    $0 = tag " = " tolower(val)
}
{ print }

$ awk -f tst.awk file
local1 = "AAA"
private = "filename_with_uppercase"

The above assumes that, as in your example, there's no leading white space in your input - it's an easy tweak to handle it if there is.

Upvotes: 1

Daweo
Daweo

Reputation: 36430

why the right hand side of the equal side isn't converted to lower case?

tolower(string) function does

Return a copy of string, with each uppercase character in the string replaced with its corresponding lowercase character. Nonalphabetic characters are left unchanged.

So you need to assign it back to get visible effect, i.e. $2=tolower($2) rather than just tolower($2) and also set FS to OFS to avoid replacing = with i.e.

'BEGIN{FS=OFS="="}/^private/{gsub(/[-/]/, "_");$2=tolower($2)} 1'

Upvotes: 2

Related Questions