grep command to search in subdirectories - unix

I have a directory named lists, and have several subdirectories in this named as lists-01, lists-02 and so on.
In every subdirectory, I have a sript called checklist.
I want to use grep command to search for "margin" in each script "checklist", and want to know the particular checklist scripts which contain the word "margin".
I tried using
grep "margin" list*/checklist
but, this is not giving any result.

You can make use of --include to select just the files you want:
grep -Rl --include='*checklist' "margin" .
I am trying to figure out how to include list-0*/ directories, still couldn't find a way.
Note also that your attempt was quite accurate. You only need to add -R for recursive:
grep -R "margin" list-[0-9]*/checklist

How about:
find lists -name checklist -type f -exec grep -H margin {} \;
That says... find, starting in the directory called lists, and all directories below, all files called checklist and look in them for the word margin printing the filename if it is in there.
If you have a modern find, you can replace the \; with + to allow each find to search more than one file and make your query more efficient.

It will search all the files named checklist recursively and then run grep command on those files to find word "margin". -l option will give you only file name and option -w is used for exact match.
find ~/list -type f -name checklist -exec grep -lw "margin" {} +

Related

Linux- command line - How to grep smt of a hidden file inside a directory of all directories

I am in a directory that has let's say 100 directories (and nothing else) and each of them has another 50 directories (and nothing else) and each of the directory(of the 50) has some hidden files. All the 50 dirs have the same name for the hidden file.
How can I grep something in the hidden file?
Example:
grep "Killed" .log
(the .log file is inside each of the 50 dirs; but I am in the root of the 100 dirs)
Using GNU grep:
grep -r --include=.log 'Killed'
This starts a recursive grep in your current directory including only files matching the name .log.
The question is a bit ambiguous. Do you have multiple "hidden" files, and you only want to search for a string in files with a particular name, or do you want to search for the string in all of the files? Either way, it's pretty trivial:
find /root/dir -type f -exec grep pattern {} \; # Search all files
find /root/dir -type f -name '*.log' -exec grep pattern {} \; # Search only in files with names matching '*.log'
You'll often want to add a -H (or specify /dev/null as a second argument) to the invocation of grep to see filenames.

How to search word on unix folders

I am trying to find a word(case sensitive) in unix server recursively under all folders/files.
i am using below syntax, not sure if its right way of searching.
grep -Rin "word" *
When you are using grep recursively, you do not need a list of files at the end, in your case -- *.
Use grep -Rin "word" from the directory you want to begin your search from.
Alternatively, find command can be used.
find <top_path> -type f | xargs grep -in "word".
top_path can be . or present working directory or a full path. -type f only finds files to speed up the search. xargs gives find results to grep as arguments.

trouble listing directories that contain files with specific file extensions

How to I list only directories that contain certain files. I am running on a Solaris box. Example, I want to list sub-directories of directory ABC that contain files that end with .out, .dat and .log .
Thanks
Something along these lines might work out for you:
find ABC/ \( -name "*.out" -o -name "*.log" \) -print | while read f
do
echo "${f%/*}"
done | sort -u
The sort -u bit could be just uniq instead, but either should work.
Should work on bash or ksh. Probably not so much on /bin/sh - you'd have to replace the variable expansion with something like echo "${f}" | sed -e 's;/[^/]*$;;' or something else that would strip off the last component of the path. dirname "${f}" would be good for that, but I don't recall if Solaris includes that utility...

Recursively search files named string.xml for certain text

This command will search all directories and subdirectories for files containing "text"
grep -r "text" *
How do i specify to search only in files that are named 'strings.xml'?
You'll want to use find for this, since grep won't work that way recursively (as far as I know). Something like this should work:
find . -name "strings.xml" -exec grep "text" "{}" \;
The find command searches starting in the current directory (.) for a file with the name strings.xml (-name "strings.xml"), and then for each found file, execute the grep command specified. The curly braces ("{}") are a placeholder that find uses to specify the name of the file it found. More detail can be found in man find.
Also note that the -r option to grep is no longer necessary, since find works recursively.
You can use the grep command:
grep -r "text" /path/to/dir/strings.xml
grep supports an --include option whose use is to recurse in directories only searching file matching PATTERN. So, try something like below:
grep -R --include 'strings.xml' text .
I also tried using find which seems to be quite faster than grep:
find ./ -name "strings.xml" -exec grep "text" '{}' \; -print
These links speak about the same issue, might help you:
'grep -R string *.txt' even when top dir doesn't have a .txt file
http://www.linuxquestions.org/questions/linux-newbie-8/run-grep-only-on-certain-files-using-wildcard-919822/
Try below command
find . -type f | xargs grep "strings\.xml"
This will run grep "strings\.xml" on every file returned by find

unix command to change directory name

Hi this is a simple question but the solution eludes me at the moment..
I can find out the folder name that I want to change the name of, and I know the command to change the name of a folder is mv
so from the current directory if i go
ls ~/relevant.directory.containing.directory.name.i.want.to.change
to which i get the name of the directory is called say lorem-ipsum-v1-3
but the directory name may change in the future but it is the only directory in the directory:
~/relevant.directory.containing.directory.name.i.want.to.change
how to i programmatically change it to a specific name like correct-files
i can do it normally by just doing something like
mv lorem-ipsum-v1-3 correct-files
but I want to start automating this so that I don't need to keep copying and pasting the directory name....
any help would be appreciated...
Something like:
find . -depth -maxdepth 1 -type d | head -n 1 | xargs -I '{}' mv '{}' correct-files
should work fine as long as only one directory should be moved.
If you are absolutely certain that relevant.directory.containing.directory.name.i.want.to.change only contains the directory you want to rename, then you can simply use a wildcard:
mv ~/relevant.directory.containing.directory.name.i.want.to.change/*/ ~/relevant.directory.containing.directory.name.i.want.to.change/correct-files
This can can also be simplified further, using bash brace expansion, to:
mv ~/relevant.directory.containing.directory.name.i.want.to.change/{*/,correct-files}
cd ~/relevant.directory.containing.directory.name.i.want.to.change
find . -type d -print | while read a ;
do
mv $a correct-files ;
done
Caveats:
No error handling
There may be a way of reversing the parameters to mv so you can use xargs instead of a while loop, but that's not standard (as far as I'm aware)
Not parameterised
If there any any subdirectories it won't work. The depth parameters on the find command are (again, AFAIK) not standard. They do exist on GNU versions but seem to be missing on Solaris
Probably others...

Resources