user3672754
user3672754

Reputation:

bash, detecting mp4 files

if [ -f *.mp4 ]; then
        for file in *.mp4; do 
                ffmpeg2theora -v 8 --nometadata  "$file"
                rm -f "$file"
        done 
fi

if [ -f *.avi ]; then
        for file in *.avi; do
                ffmpeg2theora -v 8 --nometadata  "$file"
                rm -f "$file"
        done
fi

I can't figure out why if [ -f *.mp4 ]; then is not detecting mp4 files, i use this method it to find .avi, .epub, .chm and some other extensions and it works perfectly. I wonder me if it is because of the 4. i also tried by doing if [ -f *."mp4" ]; then but it didn't work.

I find weird that for file in *.mp4; do detects .mp4 files and if [ -f *.mp4 ] not!

Upvotes: 0

Views: 2004

Answers (2)

that other guy
that other guy

Reputation: 123410

Use the bash option nullglob to allow globs to expand to zero elements. This way, the loop will simply not run if there are no matching files:

shopt -s nullglob
for file in *.mp4; do 
    ffmpeg2theora -v 8 --nometadata  "$file" && rm -f "$file" || \
        echo Problem transcoding "$file"
done 

As for [ -f *.mp4 ], it only works correctly if there is exactly one matching file, because then it expands to [ -f myfile.mp4 ].

If there are no matching files, it may still work (without nullglob) because it ends up checking for a file with an asterisk in the name, which hopefully doesn't exist.

If there are multiple files, it fails, because [ -f file1.mp4 file2.mp4 file3.mp4 ] is not valid test syntax.

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84521

if [ -f *.mp4 ]; then

There is no expansion inside the test. The test is looking for a file named *.mp4 which doesn't exist. What you should do it:

for i in *.mp4; do
    <do something>
done

Here expansion will provide all files with .mp4 extensions in the present working directory. You can also you find /path/to/dir -type f -name "*.mp4" to get your filenames as well. (note: this expects .mp4 files to be present in the directory. If not, i=*.mp4. You are safer doing:

find /path -type f -name "*.mp4" | while read i; do 
    <do whatever>
done

Upvotes: 1

Related Questions