user4670961
user4670961

Reputation: 137

Find replace "./." in awk

I am very new to using linux and I am trying to find/replace some of the text in my file.

I have successfully been able to find and replace "0/0" using gsub:

awk '{gsub(/0\/0/,"0")}; 1' filename

However, if I try to replace "./." using the same idea

awk '{gsub(/\.\/\./,"U")}; 1' filename

the output is truncated and stops at the location of the first "./." in the file. I know that "." is a special wildcard character, but I thought that having the "\" in front of it would neutralize it. I have searched but have been unable to find an explanation why the formula I used would truncate the file.

Any thoughts would be much appreciated. Thank you.

Upvotes: 0

Views: 407

Answers (2)

Ed Morton
Ed Morton

Reputation: 203684

Your awk script is fine, your input contains control-Ms, probably from being created by a Windows program. You can see them with cat -v file and use dos2unix or similar to remove them.

Upvotes: 1

dawg
dawg

Reputation: 103884

Recall that the basic outline of an awk is:

awk 'pattern { action }'

The most common patterns are regexes or tests against line counts:

awk '/FOO/ { do_something_with_a_line_with_FOO_in_it }'
awk 'FNR==10' 

The last one has no action so the default is to print the line.

But functions that return a value are also useable as patterns. gsub is a function and returns the number of substitutions.

So given:

$ echo "$txt"
abc./.def line 1
ghk/lmn won't get printed
abc./.def     abc./.def   printed

To print only lines that have a successful substitution you can do:

$ echo "$txt" | awk 'gsub(/\.\/\./,"U")'
abcUdef line 1
abcUdef     abcUdef   printed

You do not need to put gsub into an action block since you want to run it on every line and the return tells you something about what happened. The lines that successfully are matched are printed since gsub returns the number of substitutions.

If you want every line printed regardless if there is a match:

$ echo "$txt" | awk 'gsub(/\.\/\./,"U") || 1'
abcUdef line 1
ghk/lmn won't get printed
abcUdef     abcUdef   printed

Or, you can use the function as an action with an empty pattern and then a 1 with an empty action:

$ echo "$txt" | awk '{gsub(/\.\/\./,"U")} 1'
abcUdef line 1
ghk/lmn won't get printed
abcUdef     abcUdef   printed

In either case, 1 as a pattern with no action prints the line regardless if there is a match and the gsub makes the substitution if any.

The second awk is what you have. Why it is not working on your input data is probably related to you input data.

Upvotes: 1

Related Questions