find -print0 -name "* *" (whitespace) - find

Is there a way to pass all filenames containing whitespace to the pipe, or at least those containing spaces? To that end I attempted:
~/Desktop> find . -type f -mindepth 1 -maxdepth 1 -name "* *" | wc -c
0
~/Desktop> find . -type f -mindepth 1 -maxdepth 1 -print0 -name "* *" | wc -c
247
~/Desktop>
As you see, the command without -print0 accurately finds no files containing whitespace in the current directory. But with -print0 added, the -name option apparently is not interpreted as I would expect.
Even better than
-name "* *"
would be some way to specify any whitespace, not just space. Ideally this could be done in find, rather than resorting to "downstream" processing using a perl regular expression.
Ultimately, I want to pipe the filenames to a script that will replace whitespace by some character I specify.

Order matters. This will print every single name because the -print action comes before the -name filter:
find . -print -name "foo"
This will print only those named foo, because the action comes after the filter:
find . -name "foo" -print

Related

Running Find command from the directory vs. another directory

I am doing something wrong but cannot figure out what it is. I am trying to move all files in the folder (folder A) to another folder (folder B) without any subdirectories and excluding certain files
When I am in the folder I run...
cd folderA
find . -path './*' -prune -not \( -name "file1.php" -o -name "file2.txt" \) -type f -exec mv -f {} ~/folderB/ \;
That works great. But I want to run the above find command in a bash script and do no want to have to go to the folder so I tried...
find ~/folderA/ -path './*' -prune -not \( -name "file1.php" -o -name "file2.txt" \) -type f -exec mv -f {} ~/folderB/ \;
And nothing! What am I doing wrong.
Thanks in Advance
After stripping the above command down, I found the issue. for some reason -path './*' -prune does not work outside of the direct folder. Here is the command I used to get it to work outside the folder itself...
find ~/folderA/ -maxdepth 1 -not \( -name "file1.php" -o -name "file2.txt" \) -type f -exec mv -f {} ~/folderB/ \;
Again, not sure way -maxdepth 1 would work over the other method, but it did.
FYI... if you want to go further down into the subdirectories you can by changing the 1 value

Seaching for a file inside a main folder

I have a main result folder inside which there are multiple config.txt files.
However, i need to get the paths of only the config.txt files inside the netlist sub-folder, inside the main result folder, which is given.
I have tried this code, but it didn't work out.
find $mainResultPath -name "config.txt"
Here is a snippet of the code assuming we are already in the $mainResultPath
Code snippet and reqd files ticked
This should work:
find $mainResultPath -type d -name netlist | \
xargs -I {} find {} -maxdepth 1 -type f -name config.txt
i.e. first filter out the netlist directories and then search in those for config.txt files.
Example output from my test:
$ find $HOME/Documents -type f -name config.txt
/home/.../Documents/Downloads/RFC/netlist/config.txt
/home/.../Documents/config.txt
/home/.../Documents/netlist/config.txt
$ find $HOME/Documents -type d -name netlist
/home/.../Documents/Downloads/RFC/netlist
/home/.../Documents/Downloads/netlist
/home/.../Documents/netlist
$ find $HOME/Documents -type d -name netlist | xargs -I {} find {} -maxdepth 1 -name config.txt
/home/.../Documents/Downloads/RFC/netlist/config.txt
/home/.../Documents/netlist/config.txt
EDIT 2: If you don't like the 2nd find, then this works too
$ find $HOME/Documents -type d -name netlist | \
while read _d; do [ -f "${_d}/config.txt" ] && echo "${_d}/config.txt"; done

SunOS. Find files that do not contain the substring 'foo' in the file name

Now I exclude files by their extension.
find ./export/home/ ! \( -name *.log -o -name *.out -o -name *.tmp \)
But I also want to exclude files with the name containing some string 'foo'.
Need some sort of analog " like '%foo%' " (PL\SQL), to exclude files such as "1_foo2".
I can not use the GNU version of the command "find".
You are pretty close:
find ./export/home/ -type f ! \( -name "*.log" -o -name "*.out" -o
-name "*.tmp" -o -name "*foo*" \)

remove multiple files using find and rm in perl

I have a few text files in my directory which need to be removed. There are a bunch of text files in my directory:
leaves_emp1.txt
pay_emp1.txt
pf_emp1.txt
leaves_emp2.txt
pay_emp2.txt
pf_emp2.txt
[...]
I've tried using the following code to remove the files containing "emp1":
/usr/bin/find $LogDir -name \"leaves_emp1.txt\" -and -name \"pay_emp1.txt\" -and -name \"pf_emp1.txt\" -exec rm {}
But it is not working. Please help. I tried with -a and -o too. I also tried using the () for the files.
I am just using the code as follows
/usr/bin/find $LogDir -name \"*emp1.txt\" -exec rm {}
You need to avoid fork-bombs. The "exec" call in find will spawn a fork/exec with each file. I find it much easier and scalable to call something like this:
find . -type f -name '*emp1.txt' | perl -lane 'unlink $_ if -f $_' -
Note: if you want to stick with just exec, you must remember to use the "\;" at the end
find . -type f -name '*emp1.txt' -exec rm {} \;

How do I prevent find from printing .git folders?

I have a find command that I run to find files whose names contain foo.
I want to skip the .git directory. The command below works except it prints an
annoying .git any time it skips a .git directory:
find . ( -name .git ) -prune -o -name '*foo*'
How can I prevent the skipped .git directories from
printing to the standard output?
So just for better visibility:
find -name '.git*' -prune -o -name '*foo*' -print
This also omits .gitignore files; note the trailing -print to omit printing, -prune stops descending into it but without -print prints it nevertheless. Twisted C;
find . -not -wholename "./.git*" -name "*foo*"
or, more strictly, if you don't want to see .git/ but do want to search in other dirs whose name also begins with .git (.git-foo/bar/...)
find . -not -wholename "./.git" -not -wholename "./.git/*" -name "*foo*"
If your .git/ directories may not always necessarily be located at the top-level of your search directory, you will want to use -not -wholename ".*/.git" and -not -wholename ".*/.git/*".
A bit odder but more efficient because it prunes the whole .git dir:
find . -not \( -wholename "./.git" -prune \) -name "*foo*"
Try this one:
find . -name '*foo*' | grep -v '\.git'
This will still traverse into the .git directories, but won't display them. Or you can combine with your version:
find . ( -name .git ) -prune -o -name '*foo*' | grep -v '\.git'
You can also do it without grep:
find . ( -name .git ) -prune -printf '' -o -name '*foo*' -print