I have this working fine for me:
find Sources/$1-$2 -name '*' |xargs perl -pi -e "s/domain.com/$2/g"
But when I change it to the following it doesn't:
find Sources/$1-$2 -name '*.php,*.rb' |xargs perl -pi -e "s/domain.com/$2/g"
What wrong?
Here's some explanation behind the solution that others have provided.
The tests in a find command are combined with Boolean operators:
-a -and
-o -or
! -not
If you don't supply an operator, -and is the default.
find . -type f -name '*.rb' # The command as entered.
find . -type f -a -name '*.rb' # Behind the scenes.
Your search failed because it didn't find any matching files:
# Would find only files with bizarre names like 'foo.php,bar.rb'
find . -name '*.php,*.rb'
You need to supply the file extensions as separate -name tests, combined in an OR fashion.
find . -name '*.php' -o -name '*.rb'
you have to write it as:
find Sources/$1-$2 -name '*.php' -o -name '*.rb' ....
I'm guessing that you want all files then end in .php and .rb.
Try find Sources/$1-$2 \( -iname "*.php" -o -iname "*.rb" \) -print |xargs perl -pi -e "s/domain.com/$2/g"
It is much better filtering out find's result with [ef]grep. Why?
Because you can fed the grep pattern as an argument, or can read it from the config or soo. It is much easier to write: grep "$PATTERN" as constructing long find arguments with '-o'. (ofc, here are situations, where find args are better), but not in your case.
The cost is one more process. So, for you example is easy to write a script myscript.sh
find Sources/$1-$2 -print | egrep -i "$3" | xargs ...
you can call it
./myscript.sh aaa bbb ".(php|rb)$"
and the result will equivalent to more complicated
find Sources/$1-$2 \( -iname '*.php' -o -iname '*.rb' \) | xargs ...
but
why bother? If you have bash4+, (and shopt -s globstar in your .bashrc) you can simple write:
perl -pi -e '.....' Sources/aaa-bbb/**/*.{rb,php}
the ** is like a find -name.
By the way, xargs is not needed here.
find Sources/$1-$2 \( -name '*.php' -o -name '*.rb' \) \
-exec perl -i -pe "s/domain\.com/$2/g" {} +
Also notice the "." in /domain.com/ needs to be escaped.
Related
I use the following command to do some processing on text files,however it changes the symlink files aswell,is there a way to exclude symlink files from the find command and include only the actual files?
find . \( -name "*.txt" ! -name "release.txt" \) | xargs -t -n1 sed -i '' -e '/^#/d;/^nocrc=/d;/acaddr=/d;/^$/d;s/[ \t]*$//'
I am now working with "Jenkinsfile".
I need to do a "find" by type of the file extension, to do a "sed -i", ignoring some hidden directories and other folders.
I don't know the correct syntax.
Example:
def replacePath() {
sh 'sed -i "s/A\\/B/C\\/D\\/E\\/F\\/G\\/A\\/B\\/opt\\/C/g" \$(find . -type f -name "*.json" not path ..... -print0) '
Try using xargs, like so:
find . -type f -name '*.json' ... -print0 | xargs -0 sed -i 's/pattern/replacement/g'
Using xargs has fewer problems than passing argument on the command line with $(...), particularly when used with -print0, as xargs can cope with filenames containing shell metacharacters.
Mac OSX Bash Shell
I want to use find to identify anything (directories or files) which do not follow an input pattern.
This works fine:
find . -path /Users/Me/Library -prune -o \! \( -path '*.jpg' \)
However I want to have a general ability to do from a bash alias or function eg:
alias negate_find="find . -path /Users/Me/Library -prune -o \! \( -path ' "$1" ' \)"
To allow shell input of the search term (which may contain spaces). The current syntax does not work, returning unknown primary or operator on invocation. Grateful for assistance in what I am doing wrong.
Not entirely sure why, but separating the input parameter into its own string seemed to work. Here it is as a working shell function and case invariant.
negate_find () {
search="$1"
lowersearch=$(echo "$search" | awk '{print tolower($0)}')
uppersearch=$(echo "$search" | awk '{print toupper($0)}')
echo "search = $search"
find . -path $HOME/Library -prune -o \! \( -path "$lowersearch" \) -a \! \( -path "$uppersearch" \)
}
export -f negate_find
I use following find command to find and show all files having the input text pattern.
find . -type f -print|xargs grep -n "pattern"
I have many project folders each of which has its own makefile named as 'Makefile'.(no file extension, just 'Makefile')
How do i use above command to search for a certain pattern only in the files named Makefile which are present in all my project folders?
-AD.
-print is not required (at least by GNU find implementation). -name argument allows to specify filename pattern. Hence the command would be:
find . -name Makefile | xargs grep pattern
If you have spaces or odd characters in your directory paths youll need to use the null-terminated method:
find . -name Makefile -print0 | xargs -0 grep pattern
find . -type f -name 'Makefile' | xargs egrep -n "pattern"
use egrep if you have very long paths
Duplicate of : this
You can avoid the use of xargs by using -exec:
find . -type f -name 'Makefile' -exec egrep -Hn "pattern" {} \;
-H on egrep to output the full path to the matching files.
grep -R "string" /path
Please find this link
http://rulariteducation.blogspot.in/2016/03/how-to-check-particluar-string-in-linux.html
you can use ff command i.e ff -p .format. For eg ff -p *.txt
Find big files occupying large disk space
we need to combine multiple command .
find . -type f | xargs du -sk | sort -n | tail;
This part " ( -name *txt -o -name *html ) " confuses me in the code:
find $HOME \( -name \*txt -o -name \*html \) -print0 | xargs -0 grep -li vpn
Can someone explain the the brackets and "-o"? Is "-o" a command or a parameter? I know the brackets are escaped by "\" , but why are they for?
By default, the conditions in the find argument list are 'and'ed together. The -o option means 'or'.
If you wrote:
find $HOME -name \*txt -o -name \*html -print0
then there is no output action associated with the file names end with 'txt', so they would not be printed. By grouping the name options with parentheses, you get both the 'html' and 'txt' files.
Consider the example:
mkdir test-find
cd test-find
cp /dev/null file.txt
cp /dev/null file.html
The comments below have an interesting side-light on this. If the command was:
find . -name '*.txt' -o -name '*.html'
then, since no explicit action is specified for either alternative, the default -print (not -print0!) action is used for both alternatives and both files are listed. With a -print or other explicit action after one of the alternatives (but not the other), then only the alternative with the action takes effect.
find . -name '*.txt' -print -o -name '*.html'
This also suggests that you could have different actions for the different alternatives.
You could also apply other conditions, such as a modification time:
find . \( -name '*.txt' -o -name '*.html' \) -mtime +5 -print0
find . \( -name '*.txt' -mtime +5 -o -name '*.html' \) -print0
The first prints txt or html files older than 5 days (so it prints nothing for the example directory - the files are a few seconds old); the second prints txt files older than 5 days or html files of any age (so just file.html). And so on...
Thanks to DevSolar for his comments leading to this addition.
The "-o" means OR. I.e., name must end in "txt" or "html". The brackets just group the two conditions together.
The ( and ) provide a way to group search parameters for the find command. The -o is an "or" operator.
This find command will find all files ending in "txt" or "html" and pass those as arguments to the grep command.