You are not logged in.

#1 2009-08-15 19:03:52

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

[SOLVED]assigning "special" shell [variable] to awk, got problem

$ VAR='AB' ; echo "$VAR" | awk -v foo="$VAR" '{gsub(foo,"Z");print}' # [1]
Z

$ VAR='[AB]' ; echo "$VAR" | awk -v foo="$VAR" '{gsub(foo,"Z");print}' # [2]
[ZZ]

$ VAR='[AB' ; echo "$VAR" | awk -v foo="$VAR" '{gsub(foo,"Z");print}' # [3]
awk: (FILENAME=- FNR=1) fatal: Unmatched [ or [^: /[AB/

$ VAR='AB]' ; echo "$VAR" | awk -v foo="$VAR" '{gsub(foo,"Z");print}' # [4]
Z

Just read about this:

Regular Expression Operators @ The GAWK Manual wrote:

[...]
    This is called a character set. It matches any one of the characters that are enclosed in the square brackets. For example:

    [MVX]

    matches any of the characters `M', `V', or `X' in a string.

And I tried,

$ echo "[AB]" | awk '{gsub(/\[AB\]/,"Z");print}'  #[5]
Z
$ echo "[AB]" | awk '{gsub(/[AB]/,"Z");print}'  #[6]
[ZZ]

[2] is behaving like [6] when I actually want it to be acting like [5].

What syntax should I use?

Last edited by lolilolicon (2009-08-16 10:58:28)


This silver ladybug at line 28...

Offline

#2 2009-08-16 05:38:46

fumbles
Member
Registered: 2006-12-22
Posts: 246

Re: [SOLVED]assigning "special" shell [variable] to awk, got problem

I'm not entirely sure what you want to do.

[] - is part of a regular expression. So why you would add it to the thing you want to manipulate is rather confusing to me. Unless you wanted that as part of the input?

 $ echo "AB" | awk '{ gsub(/[AB]/,"Z"); print;}'
ZZ

This outputted two Z's because I said replace the letters A OR B from the input with the letter Z.

 $ echo "AB" | awk '{ gsub(/AB/,"Z"); print;}'
Z

This looks for the string AB to replace it with the character Z.
I hope that helps.
smile

Last edited by fumbles (2009-08-16 05:39:53)

Offline

#3 2009-08-16 06:30:16

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: [SOLVED]assigning "special" shell [variable] to awk, got problem

fumbles, I'm sorry I didn't explain myself clearly.

$ VAR='[AB]' ; echo "$VAR" | awk -v foo="$VAR" '{gsub(foo,"Z");print}'

outputs:
[ZZ] --> awk replaces each of A and B with Z, and left '[]' intact.
What I want is:
Z --> awk treats '[AB]' as a whole normal input, just like 'ABCD' or whatever...

Just like what I said, "[2] is behaving like [6] when I actually want it to be acting like [5]."

I need to do this because I'm writing a script where shell variable is assigned to awk variable, which contains '[]'. Like you said, awk is treating it as part of a regular expression...

EDIT:

Ok, an ugly solution::

$ VAR='[AB]'
$ VAR=$(echo "$VAR" | sed 's/\[/\\\\\[/;s/\]/\\\\\]/')  #now VAR='\\[AB\\]'
$ echo "[AB]" | awk -v foo="$VAR" '{gsub(foo,"Z");print}'
Z

This almost sovles the problem I encountered in the script.
But there should be a better answer!
Say, is there a way to turn off awk's regular expression? --> Just found out grep's -F option. How about awk??

Last edited by lolilolicon (2009-08-16 08:42:36)


This silver ladybug at line 28...

Offline

#4 2009-08-16 10:27:12

klixon
Member
From: Nederland
Registered: 2007-01-17
Posts: 525

Re: [SOLVED]assigning "special" shell [variable] to awk, got problem

VAR='[AB]'
echo "[AB]" | awk -v foo="${VAR/[/[[]}" '{gsub(foo, "Z"); print}'

${VAR/<match>/<replacement>} is a bash variable expansion trick. In this case, it replaces the first '[' it find with '[[]' (a character list contraining only a '[').  This negates it's special meaning, which automatically negates the special meaning of the following ']'

edit: typos

edit2: if var is something like '[ab][AB]' (multiple character lists), use ${VAR//[/[[]} (<pattern> starts with a '/') to replace all occurences of '['

Last edited by klixon (2009-08-16 10:31:24)


Stand back, intruder, or i'll blast you out of space! I am Klixon and I don't want any dealings with you human lifeforms. I'm a cyborg!

Offline

#5 2009-08-16 10:51:58

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: [SOLVED]assigning "special" shell [variable] to awk, got problem

Awesome. big_smile

Edit:

So we can either escape [A] with \\[A\\] or [[]A]. they both work.

But I have to escape "(A)" too, in the same manner. sed can do serial substitution in a row, how about bash's internal variable substitution?

Also, I think there's more I'd have to escape... takes some writing. It'd be best if awk had a switch like grep's -F.

Edit2:

-v foo="$(echo "$VAR" | sed 's/./[&]/g')"

The final answer!
# This replaces every character X in $VAR with [X]

Last edited by lolilolicon (2009-08-17 15:36:28)


This silver ladybug at line 28...

Offline

Board footer

Powered by FluxBB