How to delete selected files from the command line - list

I have a shell command that I run to scan my server and list all files with the name temp_file_14 in the /home directory tree as follows:
find /home . -name "temp_file_14" -exec ls -lh {} \;
I would like to change this command to have it physically delete the "found" files instead of listing them. Can someone help me with what the command should look like to perform a delete task instead of a list task?
Thanks.

This should work:
find . -name "temp_file_14" -exec rm -rf {} \;
Or this one:
find . -type f -name "temp_file_14" -exec rm -f {} \;

Related

Strip unwanted characters from a series of text files

Hi I've got a list of csv files which need to be formatted properly by getting rid of some unwanted characters.
original:
9: ["2019-4-24",-7.101458109105941]
10: ["2019-5-6",-7.050609022950812]
100: ["2019-5-6",-7.050609022950812]
I'd like to modify as:
2019-4-24,-7.101458109105941
2019-5-6,-7.050609022950812
2019-5-6,-7.050609022950812
There are dozens of files in this format and I was thinking of writing a sed command which makes a series of null substitutions for all the files in directory, but these don't seem to work.
find ./ -type f -exec sed -i '' -e "s/^[[:space:]]*//" {} \;
find ./ -type f -exec sed -i '' -e "s/\[//" {} \;
find ./ -type f -exec sed -i '' -e "s/\]//" {} \;
Many thanks for suggestions.
I found this to work on my linux machine.
find ./ -type f -exec sed -i "s/^.\+\[//;s/\"//g;s/\]//" {} \;
Which, from what I gather is equivalent to the following in macOS:
find ./ -type f -exec sed -i '' "s/^.\+\[//;s/\"//g;s/\]//" {} \;
It comprises of 3 substitutions(separated by semicolon):
s/^.\+\[// deletes everything from the start to the "[" character.
s/\"//g deletes all occurences of the double quote character.
s/\]// deletes the final "]" at the end.
And please make a backup or something if you are going to use sed -i.

How to archive each file in a folder separately?

I have many files in a folder. If I have a single file, 7z a -t7z archive1.zip -mx0 works fine. But my files are file1, file2 ... I want to archive these files separately like archive1.zip, archive2.zip ...
Note: File names are random and archive names don't necessarily be regular like archive2, archive3. All I want archive names must be parallel to file names. For example screenshot.jpg > screenshot.zip, book.pdf > book.zip
I think a good way to do this is using find :
find . -maxdepth 1 -type f -not -name "*.zip" -exec sh -c '7z a -t7z "${1%.*}.zip" -mx0 {}' sh {} \;
-maxdepth 1 is used to not enter subdirectories
-not -name "*.zip" is used to exclude archives
-exec sh -c '' sh {} is there just to be able to strip the extension from the filename
"${1%.*}.zip" transforms filename.extension into filename.zip

remove directories that do not contain media files

I am trying to make a script to delete folders that does not contain media files. The code below works but also deletes empty directories and the media could be in a sub directory of that empty folder so I do not want it deleted.
find /mnt/movies -type d '!' -exec /bin/sh -c 'ls -1 "{}"|egrep -i -q "^*\.(avi|mp4|mkv|srt)$"' ';' -exec /bin/rm -rv {} +
Example:
tree /mnt/movies/
/mnt/movies/
├── test1
│   └── 1.mp4
└── test2
└── random.txt
find /mnt/movies -type d '!' -exec /bin/sh -c 'ls -1 "{}"|egrep -i -q "^*\.(avi|mp4|mkv|srt)$"' ';' -print
/mnt/movies
/mnt/movies/test2
Above would delete /mnt/movies so would delete everything.
First, erase all the files you don't need anymore
find /mnt/movies -type f ! -name '*.mp4' ! -name '*.avi' ! -name '*.mkv' -exec rm -v {} \;
You are left with some empty directories, and some directories containing media files. Now, pretend to remove all directories:
find /mnt/movies -type d -exec rmdir --ignore-fail-on-non-empty -v {} \;
This will skip directories which are not empty, i.e. have media files.
If you don_t have Gnu rmdir (say, because you are on the Mac), use rmdir without any options, but redirect 2>/dev/null, to avoid the error messages about non-empty directories.

How to apply regex on {} parameter in Linux in find command

I want to change the file name on a certain type of files. It should run recursively.
I have almost got it and don't know how to work with the parameter {} (the absolute Path).
find $PWD -type f -name '*.jpg' -exec echo " {} " \;
For example, I want to change the extensions using reg. expressions and not the command rename etc. I need sometimes new name to pass it to a function, therefore rename is not applicable here.It should be possible to work with the parameter like in for-case with the parameter $each:
for each in /* do echo "${each\./\}.png" done
How can I apply regex on parameter {}, like here: "${each \ . / \ }.png"?
I found a workaround of the basename misbehaving when using it with find :
find $PWD -type f -name '*.jpg' -exec sh -c 'echo "$(basename "$0" .jpg).png"' {} \;
sh forces the following commands to be interpretated using your /bin/sh file. The -c option specifies arguments are passed as strings (here, your argument $0 is {}).
If you have the following files :
/home/username/image1.jpg
/home/username/Documents/image2.jpg
This will output :
image1.png
image2.png
EDIT
If you want to keep the full path, you can use this :
find $PWD -type f -name '*.jpg' -exec sh -c 'echo "${0%%.jpg}".png' {} \;
This will output :
/home/username/image1.png
/home/username/Documents/image2.png

changing folder name recursively using regex (shell)

So I want to change the name of a specific folder recursively. However, that folder isn't always at the same depth or position. I want to change the folder name from variables to constant.
So the variables folders might be located at depth 2, and/or 3, and/or 4, and/or 5, 6, etc... I do not know that
It might be
/var/me/variables/.../.../
or
/var/me/..../..../.../variables/...
or
/var/variables/..../variables/.../../variables/
What I want again is, WHEREVER there is a folder called variables, change its name to constant
I did the following code, but it doesn't work
find var -type d -exec echo `echo "{}" | sed 's/variables/constant/g'` \;
any help would be appreciated.
Thank you!!
This is fun! Here are my two cents:
find . -depth -type d -name variables -execdir mv -T {} constant \;
Rationale:
-depth avoids changing a path find later descends into; probably can be omitted.
-execdir avoids the need to play games with entire paths, so we can operate only on the directory basename
passing the -T option to mv makes it bail if a directory constant should already exist
You actually need to call mv, not echo:
find var -type d -name "*variables*" -exec mv {} `echo "{}" | sed 's/variables/constant/g'` \;
The above assumes you have directories with with string "variables" in names. If you are after directories which are called precisely "variables", then it could be a bit simpler:
find var -type d -name variables -exec mv {} constant \;
Try this find command:
find var -name "*variables*" -type d -exec bash -c 'mv "$1" "${1//variables/constant}"' - '{}' \;
Try using find with rename
find /var -type d -name 'variables' -type d -exec rename 's/variables/constant/' {} \;