How can I use the `find` command in Linux to remove non-empty directories? [closed] - linux

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
I have temp directories full of junk that all start with __temp__ (e.g. __temp__user_uploads), which I want to delete with a cleanup function. My function attempt is to run:
find . -name __temp__* -exec rm -rf '{}' \;
If I run the command and there are multiple __temp__ directories (__temp__foo and __temp__bar), I get the output:
find: __temp__foo: unknown option
If I run the command and there is only 1 __temp__ directory (__temp__foo), it is deleted and I get the output:
find: ./__temp__foo: No such file or directory
Why doesn't the command work, why is it inconsistent like that, and how can I fix it?

Use a depth-first search and quote (or escape) the shell metacharacter *:
find . -depth -name '__temp__*' -exec rm -rf '{}' \;
Explanation
Without the -depth flag, your find command will remove matching filenames and then try to descend into the (now unlinked) directories. That's the origin of the "No such file or directory" in your single __temp__ directory case.
Without quoting or escaping the *, the shell will expand that pattern, matching several __temp__whatever filenames in the current working directory. This expansion will confuse find, which is expecting options rather than filenames at that point in its argument list.

Related

Linux shell select files in directory and subdirectiry [closed]

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 1 year ago.
Improve this question
For selecting all php files in a folder , we use :
vim *.php
How to use this command for selecting *.php files in this directory and his subdirectories ?
With shell option `globstar`` in bash you can use
vim **/*.php
To enable the shell option use e.g.
shopt -s globstar
You can use find combined with xargs:
find . -type f -name '*.php' -print0 | xargs -0 vi
The find will locate all regular files matching *.php, in and below the current directory, and send all the names in a stream to xargs separated by NUL characters.
The xargs program (with a -0 matching the -print0) will then separate them into individual file names and pass as many as possible to a single vi invocation. If it can't fit them all in one invocation (unlikely, unless the number of files is truly massive), it will make multiple invocations as needed.
You could use brace expansions:
vim {,*/}*.php
How does it work
{,*/} expands to <empty> dir1/ dir2/ ...
the final command line is then: ls *.php dir1/*.php dir2/*.php ...
This only matches immediate subdirectories, so subdirectories of a subdirectory won't be included. As mentioned in the other answeres, find or globstar is better suited for that.

`find` claims it deleted the files, `ls` claims it didn't [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I tried to delete some images by matching them to a regular expression and I did this in two similar ways by now, both including piping the results of find to rm. First I found all the images that I wish to be deleted with this:
find . -type f -regex ".+-[0-9]+x[0-9]+\.jpg"
Which found a lot of results.
So I tried to delete them like this:
find . -type f -regex ".+-[0-9]+x[0-9]+\.jpg" -exec rm -rf {} \;
And then like this:
find . -type f -regex ".+-[0-9]+x[0-9]+\.jpg" | xargs rm
After both attempts, the find command no longer sees the images that I wanted to delete (when I run the first command again), but ls sees them, and so does Nautilus. Is there some kind of commit I should run in order to actually delete them from the hard disk?
I tried searching the rm man page for "commit" and the find man page for "remove", but haven't found anything significant.
Your regex doesn't match these filenames...
$ touch yellow-zone-etna-36x36.png yellow-zone-etna-615x250.png
$ find . -type f -regex ".+-[0-9]+x[0-9]+\.jpg"
$ # no output
because you have PNGs, you're looking for JPEGs, and you additionally have JPEGs that don't match the regex either.

List of All Folders and Sub-folders [closed]

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
In Linux, I want to find out all Folder/Sub-folder name and redirect to text file
I tried ls -alR > list.txt, but it gives all files+folders
You can use find
find . -type d > output.txt
or tree
tree -d > output.txt
tree, If not installed on your system.
If you are using ubuntu
sudo apt-get install tree
If you are using mac os.
brew install tree
find . -type d > list.txt
Will list all directories and subdirectories under the current path. If you want to list all of the directories under a path other than the current one, change the . to that other path.
If you want to exclude certain directories, you can filter them out with a negative condition:
find . -type d ! -name "~snapshot" > list.txt
As well as find listed in other answers, better shells allow both recurvsive globs and filtering of glob matches, so in zsh for example...
ls -lad **/*(/)
...lists all directories while keeping all the "-l" details that you want, which you'd otherwise need to recreate using something like...
find . -type d -exec ls -ld {} \;
(not quite as easy as the other answers suggest)
The benefit of find is that it's more independent of the shell - more portable, even for system() calls from within a C/C++ program etc..

Change filenames to lowercase in Ubuntu in all subdirectories [closed]

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
I know it's been asked but what I've found has not worked out so far.
The closet I came is this : rename -n 'y[A-Z]/[a-z]/' *
which works for the current directory. I'm not too good at Linux terminal so what
should I add to this command to apply it to all of the files in all the sub-directories from which I am in, thanks!
Here's one way using find and tr:
for i in $(find . -type f -name "*[A-Z]*"); do mv "$i" "$(echo $i | tr A-Z a-z)"; done
Edit; added: -name "*[A-Z]*"
This ensures that only files with capital letters are found. For example, if files with only lowercase letters are found and moved to the same file, mv will display the are the same file error.
Perl has a locale-aware lc() function which might work better:
find . -type f | perl -n -e 'chomp; system("mv", $_, lc($_))'
Note that this script handles whitespace in filenames, but not newlines. And there's no protection against collisions, if you have "ASDF.txt" and "asdf.txt" one is going to get clobbered.

scp download multiple files from multiple directories [closed]

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
first time I am using linux for work. I am trying to figure out how I can download multiple files with the same extension in multiple directories using scp.
For example:
/server/directoryA/directoryA1/nameA.txt
/server/directoryA/directoryA2/contactA.txt
/server/directoryA/directoryB1/nameB.txt
/server/directoryB/directoryB2/contactB.txt
I want to download all the *.txt file in one scp command. I can't seem to get it working.
I tried something like:
scp user#server:/server/*/*/*.txt .
I tried with -r too but doesn't seem to be working. Anyone can point me to the right command syntax? Thank you!
You can do this using ssh instead of scp:
ssh user#server 'find /server/ -name "*.txt" -print0 | xargs -0 tar -cO' | tar -xivf - -C .
this will copy all the *.txt into the current dir ".", but it will copy the directory structure too, so if you want just the txt files without the directory structure you will need to move all the downloaded txt files into the current directory by:
find -name "*.txt" -print0 | xargs -0 -I {} cp {} .
and then remove the empty directory structure:
rm ./server -r

Resources