Reputation: 227
I'm trying to find an exact match of a certain string that contains backslashes and spaces, but I can't seem to get the correct technique that only returns one match (see example). The problem occurs where there are more 'versions' of the same variable, as shown below.
Two examples of variables would be:
variable_i_want="Database\Base\location of site"
variable_dont_want="Database\Base\location of site - remote"
The file i'm searching in is structured as follows (all columns are tab seperated):
Database\Base\location of site data1 data2 data3
Database\Base\location of site - remote data1 data2 data3
Other_variable\something data1 data2 data3
My goal would be to only match the first line in this case.
Things i've tried so far:
awk -v pattern="$variable_i_want" -F\\t '$1~pattern {print $1,$2,$3}' file.txt
returns
awk: warning: escape sequence '\B' treated as plain 'B'
grep -F "$variable_i_want" file.txt
returns lines containing both matches (location of site and location of site - remote). Leaving out the -F returns nothing because it interprets the backslashes and spaces as code instead of string (i guess)
I think a possible solution would be to match the variable in combination with a regex, something like ^$variable_i_want$
but I can't get this to work in either sed/awk or grep.
So, for clarity: i only want the line containing $variable_i_want to match.
Upvotes: 4
Views: 88
Reputation: 133780
After chatting with OP got to know his/her O.S is Ubnutu, so written and tested this code with Ubuntu 16.04.6
variable_dont_want='Database\\Base\\location of site - remote'
variable_i_want='Database\\Base\\location of site'
Now run following code:
awk -v var="$variable_i_want" -v var1="$variable_dont_want" 'index($0,var) && !index($0,var1)' Input_file
Output of above code was as follows.
Database\Base\location of site data1 data2 data3
So we need to do 2 things here to make this work with awk
:
"
to take \
as a literal character, we need to tell variable that we need 2 of \
in it.\
as \\
because of awk
it should be escaped so that awk
will NOT give warning messages etc.Upvotes: 2
Reputation: 6387
If you have bash 4.4 or up, you can do
grep "^${variable_i_want@Q}$"$'\t' file.txt
The ^
matches the begining of the line, the $'\t'
matches a tab character (note, this has to be outside of the original quotes...). the ${...@Q}
escapes the backslashes and spaces in a manner that grep accepts. If you have an older version of bash, you can use the printf %q
instead:
grep "^$(printf %q "$variable_i_want")"$'\t' file.txt
or
grep "^$(printf "%q\t" "$variable_i_want")" file.txt
(since you're using printf anyways, you can have it output a literal tab character...)
example:
tmp> more file.txt
blah
Database\Base\location of site data1 data2 data3
Database\Base\location of site - remote data1 data2 data3
tmp> printf "%q\n" "$variable_i_want"
Database\\Base\\location\ of\ site
tmp> grep "^$(printf "%q" "$variable_i_want")"$'\t' file.txt
Database\Base\location of site data1 data2 data3
Upvotes: 1
Reputation: 3520
You might want to escape \B
and use the $
to enforce it to be at the end of the hook.
awk -F\\t '$1~/Database\\Base\\location of site$/ {print $1,$2,$3}' file.txt
Upvotes: 0