简体   繁体   中英

Escaping ~! in awk (bash command), backslash not last character on line

I am trying to run a bash command in the following format:

declare "test${nb}"="$(cat file.txt | awk '{if($3>0.5 && $3 !~ "ddf") $2="NA"; print $1,$2}')"

where $nb is an int (eg 2) and file.txt contains a table with various numeric and string values (I can provide more details if needed, but it should not be relevant here)

when running this, the shell substitutes !~ for the name of a file that I have (not sure why). I tried escaping this using the backslash like this:

declare "test${nb}"="$(cat file.txt | awk '{if($3>0.5 && $3 \!~ "ddf") $2="NA"; print $1,$2}')"

but then I get this error:

awk: {if($3>0.5 && $3 \!~ "ddf") $2="NA"; print $1,$2}
awk:                  ^ backslash not last character on line

I also tried having the table contained in the variable "var" and writing it this way:

declare test[$nb]=$(echo "$var" | awk '{if($3>0.5 && $3 !~ "ddf") $2="NA"; print $1,$2}')

Then there is no error, but the output is just the first field of first column of the table, which is not the case when I don't expand the variable name. For example, if I do this:

declare test2=$(echo "$var" | awk '{if($3>0.5 && $3 !~ "ddf") $2="NA"; print $1,$2}')

then it works perfectly and test2 has the expected value. But I need to be able to use any number instead of 2 (something like test[$nb]).

any idea how I could fix this? Any help will be very appreciated!

thanks

Lose the quotes:

$ declare x="$( echo '!' )"
-bash: !': event not found
$ declare x=$( echo '!' )
$ echo "$x"
!

You have a lot of other issues with your statement, though, including UUOC, using a scalar to emulate an array, non idiomatic awk syntax, etc. Try this instead:

declare test[$nb]=$( awk '{print $1, (($3 > 0.5) && ($3 !~ /ddf/) ? "NA" : $2)}' file.txt )

Are you talking about interactively entering a command, or running the command from a file (ie script)? The history expansion of !~ occurs only in interactive use. BTW, the bash manpage says: If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.

This means that, as long as you do scripting (or, more precisley, as long as you do not have an interactive shell), you don't have to worry about this special meaning of '!'.

If you have an interactive shell and history expansion bothers you, you can turn it off by

set +H

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM