LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   grep issue (https://www.linuxquestions.org/questions/linux-newbie-8/grep-issue-931523/)

jack_9 02-27-2012 05:50 AM

grep issue
 
Hello..
Can some one tell me how to grep "\t" in sting.. Please see the below details for more clarification

$ grep "a\t" a.txt
$ grep "\tb" a.txt
a\tbcdesf
$ grep -w "a\t" a.txt
$ grep -E -e "a\t" a.txt
$ cat a.txt
a\tbcdesf
$ grep "a\tbcdesf" a.txt
$


If I'm grepping "\t" with preceding character, then it's not working.. I tried the above options but still with no Luck..:(

eosbuddy 02-27-2012 06:38 AM

You will need to use the -P flag:

Code:

grep -P "\t" file.txt

grail 02-27-2012 06:52 AM

Option suggested by eosbuddy did not work for me but the -F option did :)

David the H. 02-27-2012 09:38 AM

bash/ksh have an "ansi-c style" quoting pattern. It expands any backslash characters contained in it, such as "\t", into their literal ansi/ascii equivalent. It's similar in effect to echo's "-e" option.

Code:

grep $'a\t'
See this link or the bash man page "quoting" section for more on ansi-c quoting.

http://mywiki.wooledge.org/Quotes


Another option that should work in most shells is to first hit "ctrl-v", then "tab" (or whatever). The first key combination forces the shell to insert the next keypress as a literal value.

Code:

grep 'a<ctrl-v><tab>'
Edit: I just realized that you may be referring to a literal "\t" (backslash+t) and not an actual tab. In which case your problem is that you need to escape the backslash to force grep to treat it as literal.

Code:

grep 'a\\t'
grep "a\\\t"

Notice that you may need a different number of backslash escapes when using single quotes and double quotes. This is due to the way bash handles backslashes inside double-quotes. Again, see the man page for details.

jack_9 03-05-2012 06:08 AM

David the H.

Your below observations are perfect:

Edit: I just realized that you may be referring to a literal "\t" (backslash+t) and not an actual tab. In which case your problem is that you need to escape the backslash to force grep to treat it as literal.

bash/ksh have an "ansi-c style" quoting pattern. It expands any backslash characters contained in it, such as "\t", into their literal ansi/ascii equivalent. It's similar in effect to echo's "-e" option.


However I was trying:

grep $"b\tc" file.txt is not working

And I'm doing some run time grep'ing.. so its impossible to escape "\t"

This unix box is like hell.. no optiongs like "-P" and "-F" are working here.. I also dont have rooot permission to install the latest grep

Only the following options are available :(

$ grep -h
Usage: grep -hblcnsviw pattern file . . .
$

Someone, please give some suggestions, I'm Ok to use other utilities(Like Sed/nawk etc.....)

Thnx
Jack

grail 03-05-2012 06:26 AM

I do not understand this line:
Quote:

And I'm doing some run time grep'ing.. so its impossible to escape "\t"

eosbuddy 03-05-2012 06:45 AM

Will this work?
Code:

grep "a[[:blank:]]b" file.txt

jack_9 03-05-2012 06:52 AM

Hey Grail...

Quote:

And I'm doing some run time grep'ing.. so its impossible to escape "\t"
The requirement is like: Some data are inserting into a table... the column value contains the "xxx\txxx" or "\t" is in random fashion..

I don't have control on that value.. So now I want to pass the select query putput to grep

jack_9 03-05-2012 07:45 AM

@eosbuddy: No it's not working :(

This "grep" is making me crazy

eosbuddy 03-05-2012 07:51 AM

Also, the following works for me (for a literal \t):
Code:

grep "\\\t" file.txt
Regex's are gentle souls and need a lot of patience from us mere mortals ;-)

grail 03-05-2012 08:19 AM

Ok ... I think I get you, but you will need to escape the data somehow for it to work.

So my suggestion would be like so (this is an example you will need to alter to suit):
Code:

#!/bin/bash

x="$1"

grep "${x//\\/\\\\}" $2

And to run:
Code:

./script.sh 'a\tb' file
Obviously you will get the data by other means but this should help.

jack_9 03-05-2012 08:59 AM

Grail and eosbuddy,

I agree with your approaches..
But in my case the data are more sensitive and the no. of records are also NOT small, So I'm afraid to do replace "\t" with "\\t"..the column value consist of several special characters as well.

For example..
The column value may be like this and there are also more than 40 columns and million number of records

"adnle;#\tfefferj"
"\tvwlem;"
"123\t"
" \t*112 "
"\t\t\t\s "


The values(containing "\t") are not consistent

This solaris box also dont have powerful grep utility..Many options are not available in this.. In above thread, I mentioned, which options are available in my unix box

grail 03-05-2012 10:46 AM

I am still not sure why this is not so easy?
Code:

$ cat file1
"adnle;#\tfefferj"
"\tvwlem;"
"123\t"
" \t*112 "
"\t\t\t\s "
$ cat script.sh
#!/bin/bash

while read -r i
do
    echo "${i//\\/\\\\}"
done<file1
$ ./script.sh
"adnle;#\\tfefferj"
"\\tvwlem;"
"123\\t"
" \\t*112 "
"\\t\\t\\t\\s "


eosbuddy 03-05-2012 11:43 AM

Or even this (sed is a line by line utility and should work on a minimalistic install):
Code:

$ cat file1
"adnle;#\tfefferj"
"\tvwlem;"
"123\t"
" \t*112 "
"\t\t\t\s "

and then do a
Code:

$ cat file1 |sed 's/\\t/    /g'

"adnle;#    fefferj"
"    vwlem;"
"123    "
"    *112 "
"            \s "


jack_9 03-06-2012 02:09 AM

Grail,

Your approach is again right, but in my scenario it's not simple... See my below scenario
Quote:

for ((j=1; j<=$r_cnt; j+=1))
do
rec=`sed -n "$j{p;q;}" ${file}`
grep -x "$rec" ${file}_dup

done

In above snippet;

the $rec is record of a table (captured in External File)
table value may be like

1 2 3 4 adlkjlfd;%114 \ttow\p felk&\t* ..... So on...

and the grep is not able to capture "\t" and it's failing as there is no match found..

For example:
if
rec=`echo "1 2 3 4 adlkjlfd;%114 \ttow\p felk&\t*"`

then

"grep -x "$rec" ${file}_dup" is not working

See, If I do replacement in file for "\t" or looping in again, its like repeated traverse through the file.
Which is again bad coding because of time complexity

Grail, Please let me know, if you have any doubt for my xplanations.. I hope, you will provide me the best solutions :) have a good day...


eosbuddy:-

This may or may not be <tab> it's literal "\t"


Cheers!!!
Jack

eosbuddy 03-06-2012 02:11 AM

@jack_9: the examples I've given in my previous 2 posts are for literal "\t" - particularly the sed example (you can convert the 4 spaces (before the /g) to whatever else you'd like to be in there).

grail 03-06-2012 02:51 AM

Yeah I am still not with you :(

Using your example:

If we assume that the following returns "1 2 3 4 adlkjlfd;%114 \ttow\p felk&\t*"
Code:

rec=`sed -n "$j{p;q;}" ${file}`
So when we go to the grep line why can't we:
Code:

grep -x "${rec//\\/\\\\}" ${file}_dup

jack_9 03-06-2012 03:38 AM

Dunno :( Its not working.....



$ grep -x "${rec//\\/\\\\}" rec1
$ echo $?
1
$ echo "${rec//\\/\\\\}"
1 2 3 4 adlkjlfd;%114 \\ttow\\p felk&\\t*
$ echo $rec
1 2 3 4 adlkjlfd;%114 \ttow\p felk&\t*
$ cat rec1
1 2 3 4 adlkjlfd;%114 \ttow\p felk&\t*
$

grail 03-06-2012 04:24 AM

hmmm ... seems your -x on grep is putting you between a rock and a hard place. I think it is interpreting the \\ to be 2 slashes but when left as a single it thinks of \t
as a tab. I would add that without -x it works just fine.

jack_9 03-06-2012 05:01 AM

Yeah Grail.. you are correct.. the grep(in my unix box) is really poor..
And I did not find any other option except "-x" because I need to match the entire line..

If I wont give "-x" then, the half of line will also match, which wont give me the right result or pattern matching... I think you understood my point..

grail 03-06-2012 05:32 AM

You could put start and end, ie ^$, around the string but you actually have another issue to. It appears that the current solution also has an issue that the final asterisk is not
matched unless escaped. I must say I would wonder who in their right mind would have a database filled with this gibberish??

jack_9 03-06-2012 06:02 AM

Yeah, grail.. u r correct..
Finger crossed :)
Sybase database is also not very reliable in joins for such values(Like Space)

So, I wanted my script, should work on file level instead of database level..but in file level also I'm facing this issue..

I was happy with my Linux box and lots of options for grep and was able to do many stuffs..
However this unix box(and Sybase) is not allowing me to free up.. :(


All times are GMT -5. The time now is 11:00 PM.