Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I need a unix command to list all files that contains 'foo' in their name ?
We have two commands that do that : grep command and find command !!
what's the best?
Thanks
The find command by itself suffices (unless you want to include files in directories whose name includes "foo"):
find / -type f -name '*foo*'
That checks the leaf name (last part) of the pathnames. If you piped the result of find through grep in a similar way:
find / -type f | grep foo
it would match those files, as well as all files (and directories) inside directories whose name includes "foo".
To filter the list in a more interesting way, you can use grep, which supports regular expressions and other features. For example, you could do
find / -type f | grep -i foo
to match "foo" ignoring case.
But if you want to look at the contents of files, that is grep-specific:
find / -type f -exec grep foo {} +
Further reading:
find
grep
Use find to list all files on the system.
Pair that up with grep to search for a specific file name.
like this:
find / -type f -exec grep -i -r "*foo*" {}
Related
This question already has answers here:
How do you exclude symlinks in a grep?
(5 answers)
Closed 5 years ago.
How can I ignore to follow symbolic links with grep ?
I tried to use with grep -R but it don't help me
Try grep -r instead. It doesn't follow symbolic links .... according to the manual entry!
Another option would be to use find <dir> -P -type f ... | xargs grep .... (Or leave out the -P because not following symlinks is default behavior for find. If you have whitespace in pathnames, use find ... -path0 and xargs -0.)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
find . -name "recovery_script" | xargs
I try to execute but it only prints it. How can I run it parallel ?
find . -name "recovery_script" | xargs -n1 -P8 sh
for 8 processes in parallel.
Provided there are at least 8 places where "recovery_script" can be found.
The -n1 argument is necessary to feed one argument at a time to sh. Otherwise, xargs will feed a reasonable number of arguments all at once to sh, meaning it's trying to execute something like
sh dir1/recovery_script dir2/recovery_script dir3/recovery_script ...
instead of
sh dir1/recovery_script
sh dir2/recovery_script
sh dir3/recovery_script
...
in parallel.
Bonus: your command can be longer than just a single command, including options. I often use nice to allow other processes to still continue without problems:
find . -name "recovery_script" | xargs -n1 -P8 nice -n19
where -n19 is an option to nice, not to xargs.
(Aside: if you ever use wildcards for -name in find, use the -print0 option to find, and the -0 option to xargs: that separates output and input by the null character, instead of whitespace (since the latter may be part of the filename). Since you search for the full name here, that is not a problem.)
From the xargs manual page:
SYNOPSIS: xargs ... [command [initial-arguments]]
and
... and executes the command (default is /bin/echo) one or more times with any initial-arguments followed by items read from standard input.
The default behaviour is thus to echo whatever arguments you give to xargs. Providing a command like sh (perhaps depending on what executable you're trying to run) then works.
This solution is not using xargs but a simple bash script. Maybe it can help:
#!/bin/sh
for i in $(find -name recovery_script)
do
{
echo "Started $i"
$i
echo "Ended $i"
} &
done
wait
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" {} +
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
What's the best way to copy a whole recursive directory structure where all files are just copied as symbolic links?
In other words, the copy should mirror the whole directory (sub-)structure of the original directory but each file should just be a symbolic link.
I guess ... first you want to make your directories...
cd "$source"
find . -type d -exec mkdir -p "$target/{}" \;
Next, make your symlinks...
cd "$source"
find . -type f -print | (
cd "$target"
while read one; do
deep=$(echo "${one:2}" | sed 's:[^/][^/]*:..:g')
ln -s "${deep:3}/${one:2}" "$(basename "$one")"
done
)
Note that this will fail if you have linefeeds or possibly other odd characters in your filenames. I can't think of a quick way out of this (I mean by doing this in a find -exec), since you need to calculate $deep differently for each level of directory.
Also, this is untested, and I'm not planning to test it. If it gives you inspiration, that's great. :)
This is not the solution that will make symbolic links but it will make hard links.
cp -rl $src $dst
Cons:
it is harder to see if the file replaced in the tree
the both trees should be on the same filesystem
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
Is there a way to get just the file's owner and group, separated by space in unix shell?
I'm trying to write a script to find the owner of all the files in a directory and print it (in a specific format, can't use ls -la).
ls -l | awk '{print $3, $4 }'
That'll do it
Use the stat command, if available on your version of UNIX:
$ stat -c "%U %G" /etc/passwd
root root
or, to do this operation for all files in a directory and print the name of each file too:
$ stat -c "%n %U %G" *
GNU find has the -printf option which will do this for you:
# if you want just the files in the directory, no recursion
find "$dir" -maxdepth 1 -type f -printf "%u %g\n"
# if you want all the files from here down
find "$dir" -type f -printf "%u %g\n"
# if you need the filename as well for disambiguation, stick a %f in there
find "$dir" -maxdepth 1 -type f -printf "%u %g %f\n"
Other systems might have this as gfind.
ls -l | cut -f3,4 -d" " | tail -n +2