How to get the grep command to search a specified directory? - bash

I am trying to create a bash command that uses grep to search arguments in a specified directory. How would I do this. At the moment it only searches for the current directory. I have tried the following but it doesn't work:
ls $directoryName -l | grep "$1"

I'm sure there's a better way do do this but
ls -lah $directoryName > /usr/tmp/test
grep $1 /usr/tmp/test
rm /usr/tmp/test
Edit: You might have better luck using find though.
find $directoryName -name $1

Working example:
grep -e "Exec" /usr/share/applications/*

The following example will search recursively (including in sub-folders and hidden files) for an argument or pattern in a literal way (it will search for '$1' literally, not allowing substitution):
grep -re '$1' /folder/folder
Now, if you want to search for the value of the argument, then the code below would allow for substitution and do that:
grep -re "$1" /folder/folder

Related

How to pipe a specific file to a find command?

I am trying to redirect a specific file to the "find" command in bash shell by using the below command.
ls sample.txt | find -name "*ple*"
I would like to search the sub string ple in the filename sample.txt which I have passed, but the above command is checking for the match from all the files in the directory. It is not searching for the match in the specific file which I have passed using pipe.
You need to use the grep command not find, which crawls the file system.
If you are looking for the sub string "ple" in the filename "sample.txt", then this code would do what you need:
mkdir -p /tmp/holder-file/ && cp /directory/sample.txt /tmp/holder-file/ && ls /tmp/holder-file/ | grep -e "ple"
Not super elegant but works great.
Edit: Thanks to Benjamin W. who came with a more elegant solution:
grep -e 'ple' <<< '/directory/sample.txt'

grep -l 'string' path prints the path followed by 'is a directory'

I have no idea what I'm doing wrong. I'm trying to get grep to return the string matches in files in a directory, but instead it is just returning the path followed by 'is a directory'. I looked in the man pages and did grep --help, but I do not understand the syntax.
You need -r for recursive.
The following will search through some_directory looking for files that contain something:
grep -l -r something some_directory
If you don't specify -r, grep thinks that you are trying to search the directory itself and it appropriately responds:
grep: some_directory: Is a directory
With -r, grep understands that you want to look for files in the directory tree starting with some_directory.
To retrieve file names without paths
To remove the paths from the file names, we can, for example, use basename:
grep --null -l -r something some_directory | xargs -0 -n1 basename
If you just want to eliminate some_directory while keeping any subdirectories, then use:
( cd some_directory; grep -l -r something . )

Finding all commands excluding "."

So far I have this:
ls /usr/bin | grep "^[\.]"
The cmd still gets files with a "." in there.
I have looked at [[:punct:]] but still returns the same thing.
There's grep -v to exclude things. So try
ls /usr/bin | grep -v \\.
man grep says
-v, --invert-match
Selected lines are those not matching any of the specified patterns.
It's generally considered a bad idea to parse ls.
If I understand you correctly, you want all files in /usr/bin that don't have a dot in the name. You can use find to do that:
find /usr/bin -not -name "*.*"
It is more portable (thanks #Adrian) to use a ! instead of -not:
find /usr/bin ! -name "*.*"
Not really clear, what you want:
your command:
ls /usr/bin | grep "^[\.]"
mean, filter the output from ls to show only files, what are start with a dot.
grep "^[\.]"
^ ^^ - escaped dot
+- at the begining of the line
If you want, exclude all files what contains dot, use
ls /usr/bin | grep -v '\.' #or see HenrikN's answer and comments (grep -vF .)
it you want exclude only entries what are starting with dot, use
grep '^[^\.]'
whats mean anything, but dot at the start
Ps: anyway, parsing output form ls is usually an very bad idea. (http://mywiki.wooledge.org/ParsingLs)
You can change your regex to exclude files starting with ".":
ls -a /usr/bin | grep "^[^.]"
This regex selects only files which do not have "." at the start. By the way only ls -a shows files that starts with ".". How did you manage to get them without "-a" ?
This can be achieved with pure bash, if the extglob shell option is enabled.
shopt -s extglob
echo /usr/bin/!(*.*)
# or alternatively:
echo /usr/bin/+([!.])
You may replace echo with ls -d if you want to pipe the list to another command line-wise.
I think you are referring to the current working directory and parent dirctory and not a command with "a dot" in it.
Try this as you probably have ls aliased:
/bin/ls /usr/bin

Grep in bash script giving no results

I wanted to make a little script to save me some typing, but unfortunately I get no output:
#!/bin/bash
grep -Hnr \"$1\" --include \"*cpp\" --include \"*h\" $2
I played quite a lot with echo and different use of quotes, and convinced myself that line really expands into what I want, but the only way I could actually get any output is with this:
#!/bin/bash
GREP="grep -Hnr \"$1\" --include \"*cpp\" --include \"*h\" $2"
echo $GREP | bash
An example usage would be:
srcgrep "dynamic_cast" src
I've tried this in a simple example directory to rule out anything weird with links, permissions, etc.
So, of course I can just use the second, but any idea what's wrong in the first case? Thanks.
$ grep -V
grep (GNU grep) 2.5.1
...
$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
...
Why not just:
#!/bin/bash
grep -Hnr "$1" --include "*cpp" --include "*h" $2
?
So, GNU or someone's found a way to screw up grep with completely inappropriate options. Awesome. They really should have considered the UNIX philosophy of "Do one thing and do it well". grep is for searching for text in files, it's not for finding files. There's a perfectly good command with a somewhat obvious name for FINDing files.
find "$2" -name '*cpp' -o -name '*h' -exec grep -Hnr "$1" {} \;
assuming "$2" in your posted example is a directory name instead of a file name as you'd expect grep to work on.

greping for a value != *.file extension

Not 100% on how to go about this.
Basically my app creates two file outputs.
file
file.ext
when searching through the directory it always returns both files. I wish only to work with
file
how can I do a grep for just the file? Or is grep even the correct command?
!grep *.ext
pseudo code ^
Why not just:
grep foobar file
or if you want to search your directory
find . -name 'file' | xargs -r grep boofar
You can try using grep 'file$', i.e. select lines ending with file and nothing after that. Alternatively you can use grep -v to invert results.
# (echo "file"; echo "file.txt") | grep file$
file
# (echo "file"; echo "file.txt") | grep -v .ext
file
I have no idea what you are trying to do with grep, but if you want to check whether a file exists, you do simply this:
if [ -r /some/path/file ]; then
echo "File is readable."
fi
Grep has a -v flag that inverses the meaning (looks for lines that do not contain the pattern):
ls /your/directory | grep -v '\.ext$'
This will exclude every filename ending with .ext.
Try
grep -v option
-v do the inverse match
For details do $ man grep
To generate a list of all files that do not match a pattern, use -not in find. So you want:
find . -not -name '*.ext'

Resources