Trying to get this working in CentOS and bash:
- search for all mp4, mkv, avi recursively
- delete that file and replace with empty file with the same name
Trying to get this working in CentOS and bash:
To find the files use find
. To truncate the file use truncate
. I am also using xargs
to call upon truncate
. However you could use the -exec
option of find
to avoid using xargs
.
So something like this should work. (untested)
find . \( -iname '*.mkv' -o -iname '*.avi' -o -iname '*.mp4' \) -print0 | xargs -0 echo truncate -s 0
Remove the echo
after testing that it outputs the correct commands, with correct file-names.
rm -rf *
by accident is all too easy.
– j2L4e
Oct 29 '20 at 13:21
You can use the globstar
option of bash which enables the **
glob character:
globstar
If set, the pattern ** used in a pathname expansion con‐
text will match all files and zero or more directories
and subdirectories. If the pattern is followed by a /,
only directories and subdirectories match.
With that, you can use **/*.mkv
to recursively find all files or directories whose name ends with .mkv
. Next, don't think of this as deleting the original and creating a new file. All you need to do is empty the original file. The simplest way to do that is > file
. That will open the file for writing, overwriting anything that was already there. Since you don't actually write anything, it will result in an empty file.
With that in mind, consider the following example:
$ tree -h
.
├── [4.0K] dir1
│ ├── [4.0K] subdir1
│ │ ├── [ 48K] file.mp3
│ │ └── [ 53M] file.mp4
│ └── [4.0K] subdir2
│ └── [136M] file2.avi
├── [4.0K] dir2
│ ├── [399K] file.mkv
│ └── [4.0K] subdir1
│ └── [548M] file3.avi
└── [ 30M] file.avi
5 directories, 6 files
We have 6 files, 5 of which match the pattern you are looking for (dir1/subdir1/file.mp3
should not be changed). To empty the files that match the pattern you gave, you just need to do this:
$ shopt -s globstar
$ for f in **/*.mp4 **/*.avi **/*.mkv; do > "$f"; done
if we now run tree
again, you will see that all files except the mp3
one have been emptied:
$ tree -h
.
├── [4.0K] dir1
│ ├── [4.0K] subdir1
│ │ ├── [ 48K] file.mp3
│ │ └── [ 0] file.mp4
│ └── [4.0K] subdir2
│ └── [ 0] file2.avi
├── [4.0K] dir2
│ ├── [ 0] file.mkv
│ └── [4.0K] subdir1
│ └── [ 0] file3.avi
└── [ 0] file.avi
Alternatively, you can use find
as ctrl-alt-delor suggested, but there's no need for xargs
or -print0
or any of that. Simply do:
find . \( -name '*.mkv' -o -name '*.avi' -o -name '*.mp4' \) -exec sh -c ' > "$1"' mysh {} \;
:
? If : >
works, >
should also work.
– terdon
Oct 29 '20 at 13:39
>f
is like cat >f
and invites the user to type something that will end up as the content of the file(s).
– Roman Odaisky
Oct 29 '20 at 14:34