grep

so I tried to apply grep string fn and expected to get the line number the string appeared on in the file.
I used the file tom.c a simple c program that compiles and executes just so.
case 1
Code:
  $grep -n 'return 0;' /usr/home/user1/c!/tom.c
  $ 8: return 0;
so this one seemed to work. the string occurs on line 8.
case 2
Code:
$ grep -n 'printf("%f\n",func(10.0));' /usr/home/user1/c!/tom.c
$
so here it didn't complain but it didn't say anything about the line number. It didn't work.

why didn't case 2 work?????
also single quotes used for strings? anything else? what about ""?
 
If I remember right, grep can not search for multi-line patterns. That \n in your search string will probably not work. And \\n only works if the shell is interpreting the string (and removing one slash in the process), which depends on whether you used single or double quotes.

In shell, both single and double quotes are used for strings. But their semantics is different. Please read up on this.

I'm also very surprised by the "!" in your file name. Shells tend to interpret ! as a meta-character in certain circumstances, so it might have unusual effects.
 
Or use fgrep(1). Or specify the -F/--fixed-strings flag. If you care only about the line number, there is sed(1)
Bash:
sed -n '/printf("%f\\n",func(10.0));/=' '/usr/home/user1/c!/tom.c'
The = instructs sed(1) to print the line number the match was found. And don’t forget about almighty awk(1). ?​
If I remember right, grep can not search for multi-line patterns. […]
Uhm, does C even permit multi‑line string literals? I don’t think so.​
[…] And \\n only works if the shell is interpreting the string […]
Nope, web9452 uses single quotes. You can verify the \\n is passed as is by setting​
Bash:
set -o xtrace
 
It is grep that excludes the backslash.
Code:
$ grep -n 'printf("%s\n", path);' /usr/src/bin/mkdir/mkdir.c
grep: trailing backslash (\)
$ grep -n 'printf("%s\\n", path);' /usr/src/bin/mkdir/mkdir.c
202:                    printf("%s\n", path);
$ fgrep -n 'printf("%s\n", path);' /usr/src/bin/mkdir/mkdir.c
202:                    printf("%s\n", path);
 
Simple grep use Basic Regular Expressions (BRE). With BRE, the following meta-characters recognized
^ $ . [ ] *
grep with -E use Extended Expressions (ERE), the following meta-characters added
( ) { } ? + |
sometimes in aliases used "grep = grep -E", check this.
In case of ERE all "()" must be "\"
 
Uhm, does C even permit multi‑line string literals? I don’t think so.
The C language itself allows any character other than nul in strings. And it uses "\n" to indicate newline. So I can write "a\nb\nc" to have a 3-line string in the source code. But C is not grep.

(Actually, C allows nul in string literals ... but what you end up with in memory is in practice two strings, since most string handling functions in C interpret the nul as and end character.)
 
grep -n 'printf("%f\\n",func(10.0));' /usr/home/user1/c!/tom.c

you may also want to escape the dot otherwise will match func(1000) func(1050) etc (dot is wildcard in regex)
 
well I tried it before I got this message. But you are right. evidently backslash is a special character not only to the shell but also grep.
the single quotes got the shell to back off ( I think) but you have to escape it to satisfy grep? anyway it works. I don't understand your comment about
regex yet.
 
Or use fgrep(1). Or specify the -F/--fixed-strings flag. If you care only about the line number, there is sed(1)
Bash:
sed -n '/printf("%f\\n",func(10.0));/=' '/usr/home/user1/c!/tom.c'
The = instructs sed(1) to print the line number the match was found. And don’t forget about almighty awk(1). ?

Uhm, does C even permit multi‑line string literals? I don’t think so.

Nope, web9452 uses single quotes. You can verify the \\n is passed as is by setting​
Bash:
set -o xtrace
sed seems to very powerful. not up to speed on it yet
 
If I remember right, grep can not search for multi-line patterns. That \n in your search string will probably not work. And \\n only works if the shell is interpreting the string (and removing one slash in the process), which depends on whether you used single or double quotes.

In shell, both single and double quotes are used for strings. But their semantics is different. Please read up on this.

I'm also very surprised by the "!" in your file name. Shells tend to interpret ! as a meta-character in certain circumstances, so it might have unusual effects.
any recommendations on where I would go to read up on single and double quotes?? thankyou.
 
any recommendations on where I would go to read up on single and double quotes?? thankyou.
Start with "man sh" (or man csh or man bash), it will explain it. To make it easier to read, the FreeBSD project keeps all man pages on the web: sh() csh() bash() and so on.

I don't know any good shell tutorials on the web. In the old days, when information was carried on paper, O'Reilly had a really good bash book, which was a joy to read. Just looked it up: "Learning the bash shell", by Cameron Newham. I'm sure an older edition from a used book store would do fine.
 
I don't know any good shell tutorials on the web.
Agree. Good stuff is hard to find.
O'Reilly's books are always a good recommendation.

any recommendations on where I would go to read up on single and double quotes?

Since for learning everybody's experiences are different what's good,
I list here what I used to learn bash-scripting.
Nothing of it is perfect, but together it may a start:

Advanced Bash-Scripting Guide, by Mendel Cooper not maintained anymore, but comprehensive
Learn X in Y minutes Where X=bash brief, in several languages

Lhunath's BashGuide
The Bash Guide academy

Wikipedia, Linux-Praxisbuch/ Shellprogrammierung, very good, but by now in german only

And of course the book would be a good choice:
Cameron Newham 'Learning the bash Shell, 3rd Edition', O’Reilly
 
Yes, because in grep you need \ for certain things, e.g. to use | as "or":
Code:
$ grep -n 'foo\|bar' /tmp/000
3:foo
4:bar
i tried this with my tom.c file and it didn't work? Maybe I don't understand how you are using the pipe character: |
 
use | for or, what do you use for and??
What's the scenario of using "and"? If two strings at the same line you just use .* between them.

i tried this with my tom.c file and it didn't work? Maybe I don't understand how you are using the pipe character: |
Not sure what's wrong in your case, it works here with sh, csh and bash. Maybe you can share the actual text from your file.
 
Back
Top