'Sed' not working on result of 'find' with multiple parameters - linux

I'm trying to do a find and replace function, finding files which match a criteria then find/replace text within them.
Find statement (works find and returns list of files):
find / -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \)
Sed find/replace:
sed -i 's/find/replace/g' {} \;
Putting together:
find / -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \) -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
However this does not seem to work. Removing some 'find' parameters causes it to work, for example this works:
find / -type f -name "*.properties" -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
How can I get sed to work with the extended 'find' parameters?
Currently these two 'find' statements return exactly the same result in a test folder with only 2 files:
find /var/tmp/ipreplace/ -type f -name "*.properties"
find /var/tmp/ipreplace/ -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \)

I guess the use of -path parameter in your find command is wrong.
Try the following:
find / -not \( -path '/tmp' -prune \) -not \( -path '/var/tmp' -prune \) -type f -name "*.properties" -o -name "*.xml" -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
Look at this post for reference

Related

-exec option of the find command does not work as expected on Ubuntu

I am doing some practice on find command but I don't get the expected result when I attempt to use -execoption of it. The command I wrote just works without -exec option as the following:
$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \)
/home/baki/.bashrc
/home/baki/.bash_logout
/home/baki/.cache/motd.legal-displayed
/home/baki/.config/wslu/baseexec
/home/baki/.config/wslu/oemcp
/home/baki/.gitconfig
/home/baki/.landscape/sysinfo.log
/home/baki/.motd_shown
/home/baki/.profile
/home/baki/.ssh/known_hosts
/home/baki/.sudo_as_admin_successful
/home/baki/ssh_start
/home/baki/token
However, when I add the -exec option to the end of the command, it doesn't give any output:
find ~ \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \) -exec ls -l '{}' ';'
I have searched about it but I couldn't find a piece of useful information that can solve my problem.
Is my command wrong or is it about something else?
Thank you for your help.
The default -and operation has higher precedence than -or. Use extra parentheses:
find ~ \( \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \) \) -exec ls -l '{}' ';'
You can probably omit the inner parentheses in this case.

FInd patternf for multiple pattern of files

I need to search for multiple pattern of files and check their mtime and if it morethan 30 days then delete all the files. I am using the below command but it's deleting only one pattern of file and not all. Kindly let me know where is the mistake in my command.
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -print -exec rm '{}' +
Try escaping parentheses in the command and adding a wildcard character:
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -exec rm {} \+

How to remove certain pattern files except another certain pattern files from a list?

I have many file with name chr1_gene_*.raw. I would like to keep some of them. So I use following command.
find . -maxdepth 1 -type f -name "*.raw" -not -name "chr1_gene_448.raw" -not -name "chr1_gene_1914.raw" -not -name "chr1_gene_2456.raw" -not -name "chr1_gene_1554.raw" -not -name "chr1_gene_2024.raw" -not -name "chr1_gene_35.raw" -not -name "chr1_gene_509.raw" -not -name "chr1_gene_1952.raw" -not -name "chr1_gene_575.raw" -not -name "chr1_gene_2249.raw" -not -name "chr1_gene_272.raw" -not -name "chr1_gene_2158.raw" -exec rm -rf {} \;
Sometimes there are too many files I want to keep. I do not want to type "-not -name " too many times. Is there a way to put a list in "-not -name"?
You may achieve this using a script say notnamescript.sh :
#!/bin/bash
while read line
do
echo "-not -name " $line
done<notnamelist
Put all the -not -name names in a file called notnamelist. Remember there
should be no trailing empty lines.
find . -maxdepth 1 -type f -name "*.name" $( ./notnamescript.sh ) -exec rm -rf {} \;

find command how to combine OR and AND

I would like to find all php and js files inside a directory and exclude one of sub directory.
I may have to exclude more than one sub directory in the future.
I tried :
find /home/jul/here -type f -iname "*.php" -o -iname "*.js" ! -path "/home/jul/here/exclude/*"
Problem is that it is excluding only js file from /home/jul/here/exclude.
Is there a way to put some kind of parentheses?
find (something OR something else) AND exclude THIS
find /home/jul/here -type f \( -iname "*.php" -o -iname "*.js" \) ! -path "/home/jul/here/exclude/*"
You need to add the exclusion pattern after each group of files. So something like this should work:
find /home/jul/here -type f -iname "*.php" ! -path "/home/jul/here/exclude/*" -o -iname "*.js" ! -path "/home/jul/here/exclude/*"
Or maybe better with a variable:
EXCLUDE=/home/jul/here/exclude
find /home/jul/here -type f -iname "*.php" ! -path "$EXCLUDE/*" -o -iname "*.js" ! -path "$EXCLUDE/*"

find command search only non hidden directories

In the following command i want to search only only the directories which are non hidden how can i do this using the following command .Iwant to ignore hidden directories while searching the log file
find /home/tom/project/ -name '.log.txt'
ls /home/tom/project/
dir1
dir2
.backup
.snapshot/
.ignore/
Try
find /home/tom/project -type d -name '.*' -prune -o -name .log.txt -print
This will find all files but ignore those that start with a dot so hidden files.
find /home/tom/project/ -type f \( -iname ".log.txt" ! -iname ".*" \)
EDIT:
If the above those not work, this should do the trick. It has a better regex.
find /home/tom/project/ \( ! -regex '.*/\..*' \) -type f -name ".log.txt"
EDIT2:
The following will exclude hidden folders but will search for the hidden files that have the requested pattern:
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -type f -name ".log.txt"
EDIT3:
The grep solution :) if this doesn't work i'm lost :)
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -exec grep -l ".log.txt" {} \;
EDIT4:
Have you tried the simple solutions?
find /home/tom/project/ -type f -name ".log.txt"
OR
find /home/tom/project/ -type f -name "*" -exec grep -l ".log.txt" {} \;

Resources