How to delete all files except directories? - bash

I was searching unsuccessfully for a solution to delete all the files inside a working directory except for the subdirectories inside.
I found a way to delete all the files inside all the directories, but I'm looking for a way to delete only the files on the same "level" I'm on.

find . -maxdepth 1 -type f -print0 | xargs -0 rm
The find command recursively searches a directory for files and folders that match the specified expressions.
-maxdepth 1 will only search the current level (when used with . or the top level when a directory is used instead), effectively turning of the recursive search feature
-type f specifies only files, and all files
#chepner recommended an improvement on the above to simply use
find . -maxdepth 1 -type f -delete
Not sure why I didn't think of it in the first place but anyway.

I think it is as easy as this:
$ rm *
when inside the working directory.
I've tested it and it worked - it deleted all files in the working directory and didn't affected any files inside any subdirectory.
Keep in mind, that it if you want to remove hidden files as well, then you need:
$ rm * .*

Related

removing directory and sub directory which is not present in the list

This is my directory structure
find -type f -print0 | xargs -0 ls -t
./lisst.txt ./SAMN03272855/SRR1734376/SRR1734376_1.fastq.gz
./SAMN03272854/SRR1734375/SRR1734375_2.fastq.gz ./SAMN07605670/SRR6006890/SRR6006890_2.fastq.gz
./SAMN03272854/SRR1734375/SRR1734375_1.fastq.gz ./SAMN07605670/SRR6006890/SRR6006890_1.fastq.gz
./SAMN03272855/SRR1734376/SRR1734376_2.fastq.gz
So this is a small subset of my folder/files where i have around 70.
I have a made a list of files which i want to keep and other i would like to delete.
My list.txt contains SAMN03272854,SAMN03272855 but I want to remove SAMN07605670.
I ran this
find . ! -name 'lisst.txt' -type d -exec rm -vrf {} +
It removed everything
QUESTION UPDATE
In my list it contains the folder i want to keep and the one which are not there are to be removed.
The folders which are to be removed also contains subdirectories and files. I want to remove everything
Your command selects each directory in the tree, except a directories of the funny name lisst.txt. Once it finds a directory, you do a recursive remove of this directory. No surprise that your files are gone.
You can't use rm -r when you want to spare certain files from deletion. This means that you also can't remove a directory, which somewhere below in its subtree has a file you want to keep.
I would run two find commands: The first removes all the files, ignoring directories, and second one removes all directories, which are empty (bottom-up). Assuming that SAMN03272854 is indeed a file (as you told us in your question), this would be:
find . -type f \( ! \( -name SAMN03272854 -o -name SAMN03272855 \) \) -exec rm {}
find . -depth -type d -exec rmdir {} 2>/dev/null
The error redirection in the latter command suppresses messages from rmdir for directories which still contain files you want to keep. Of course other messages are also suppressed. I would during debugging run the command without error redirection, to see whether it is basically correct.
Things would get more complicated, if you have files and directories to keep, because to keep a directory likely implies to keep all the files below it. In this case, you can use the -prune option of find, which excludes directories including their subdirectories from being processed. See the find man page, which gives examples for this.

Trying to find files containing an identifier, then move them to a new directory within terminal

I'm a beginner with this stuff and seem to be running into an issue.
Basically, I have many files with names containing a keyword (let's call it "Category1") within a directory. For example:
ABC-Category1-XYZ.txt
I'm trying to move them from a directory into another directory with the same name as the keyword.
I started with this:
find /path_A -name "*Category1*" -exec mv {} /path_A/Category1 \;
It spit out something like this:
mv: rename /path_A/Category1 to /path_A/Category1/Category1: Invalid
Argument
So I did some fiddling and hypothesized that the problem was caused by the command trying to move the directory Category1 into itself(maybe). I decided to exclude directories from the search so it would only attempt to move files. I came up with this:
find /path_A -name "*Category1*" \(! -type d \) -exec mv {} /path_A/Category1 \;
This did move the files from their original location to where I wanted them, but it still gave me something like:
mv: /path_A/Category1/ABC-Category1-XYZ.txt and
/path_A/Category1/ABC-Category1-XYZ.txt are identical
I'm no expert, so I could be wrong... but I believe the command is trying to find and move the files from their original directory, then find them again. The directory Category1 is a subdirectory of the starting point, /path_A, So i believe it is finding the files it just moved in the directory Category1 and attempting to move them again.
Can anyone help me fix this issue?
You are creating new files that find tries to process. Safest approach is to move them somewhere else not in the path_A you are searching with find.
Or you can use prune to ignore that directory if you don't have any other directory matching:
find /path_A -name '*Category1*' -prune -type f -exec mv {} /path_A/Category1/ \;
Although another post has been accepted, let me post a proper answer.
Would you please try:
find /path_A -name 'Category1' -prune -o -type f -name '*Category1*' -exec mv -- {} /path_A/Category1/ \;
The option -prune is rather a command than a condition. It tells find to
ignore the directory tree specified by the conditions before -prune.
In this case it excludes the directory Category1 from the search.
The following -o is logical OR and may be interpreted something like instead or else. The order of the options makes difference.
Please be noticed the 1st category1 is the directory name to exclude and the 2nd *Category1* is the filenames to find.
If you are not sure which files are the result of find, try to execute:
find /path_A -name 'Category1' -prune -o -type f -name '*Category1*' -print
then tweak the options to see the change of output.

Iteratively deleting files of a specific type

I have subfolders with .tmp files that I wish to delete, and trying to find a one-liner for doing so.
for item in folder1/*/*; do rm *.tmp; done
From this I get a bunch of messages saying:
rm: cannot remove ‘*.tmp’: No such file or directory
I get the same problem when I try doing other operations. What am I missing here?
P.S. I know I could recursively delete without a for loop with rm -rf *.tmp but I would like to know how to do it using an iterative loop, so that I can use it to perform other actions apart from rm by just replacing the "action" part of the statement.
Thanks in advance,
Jan
You can use:
find folder1 -mindepth 2 -maxdepth 2 -type f -name "*.tmp" -exec rm -f {} \;
This is going to find files (-type f) in the second directory level only (-mindept 2 -maxdepth 2) which name end with "tmp", and delete them.
You can try with "ls" instead of "rm" first, to check if the command is finding what you are looking for.

Mac Terminal command move files from subdirectory to parent

On my Mac I amm trying to move hundreds of files on my NAS drive, from a parent directory with a load of subdirectories (and possibly directories inside them) and put all of the files into one folder.
They don't have the same file extension for all the files.
Is anyone able to help with the terminal command I need to do this? So far I know that find . -type f will list all the files in the directory and subdirectories but Im unsure how to tell it to get them to move them all into another folder.
For anyone else who may have this same issue:
Ive managed to extract just the .jpg's and put them in the parent folder.
find . -type f -iname '*.jpg' -mindepth 2 -print0 | xargs -0 -I{} mv -n '{}' .
Not quite what I wanted - I was hoping to get every single file and put it into a completely different folder if possible but this has got me further than before.
Go inside the source parent directory and use:
find . -type f -exec mv "$PWD"/{} <destination directory> \;
If you want to move all the files to parent directory itself, use it as the destination directory.

shell find files in current directory only

I am trying to display a list of files from my current folder. The files must be modified within the last n days but - and here comes my problem - they must belong to current folder only. For example, I have a folder: 1. This folder contains a file test.txt and another folder: 11. This folder contains a file: test.txt and another folder 111.
I'm using find -mtime in order to get the files modified within the past n days, but this finds the files recursively - in the subfolders. I need to get only the file from current folder: /1/test.txt.
I tried to use the option -maxdeptx but id doesn't work, it is not recognized.
Any ideas will be appreciated.
Thanks!
Use the -prune primary to prevent recusing into subdirectories.
find /1 -prune -mtime ...
-prune is a standard option; -maxdepth is a GNU extension. Note that -maxdepth 1 and -prune are roughly equivalent, that is, -maxdepth generalizes the -prune primary to support a limited form of directory following.

Resources