34

Extracting the base name of a file in Bash

 4 years ago
source link: https://www.tuicool.com/articles/YjUrm2i
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

I have a handy bash script that transcodes videos using Don Meton’s video_transcoding tools . This script was written in a hurry and one limitation it had was that it re-transcoded any source file even if the output file already existed.

The script looked like this:

#!/usr/bin/env bash
 
readonly source_dir="${1:-MKV}"
readonly output_dir="${2:-MP4}"
 
for file in "$source_dir"/*.mkv; do
    ./transcode.sh "$file" "$output_dir"
done

What it should do is only run transcode.sh if the output file doesn’t exist, so I updated it.

Parameter expansion to the rescue!

I needed to extract the base name and then construct the target filename in order to test for its existence. To extract the base name of the file, I used parameter expansion:

filename=${file##*/}
basename=${filename%.*}

The first line removes the directory portion of file , This works by using the ##[word] expansion which removes the largest prefix pattern which means that for */ it removes everything up to the last / in the string – i.e. any directory paths.

The second line removes the extension from the filename by using the %[word] expansion. This removes the smallest suffix pattern on the string: for .* , it removes the from the last . to the end of the string, and so removes the extension.

I can then create the target by concatenating the output_dir , basename and the .mp4 extension and then test for the target file’s existence.

The final script is now:

#!/usr/bin/env bash
 
readonly source_dir="${1:-MKV}"
readonly output_dir="${2:-MP4}"
 
for file in "$source_dir"/*.jpg; do
    filename=${file##*/}
    basename=${filename%.*}
    target="${output_dir}/${basename}.mp4"
    if [ ! -f "$target" ]; then
        ./transcode.sh "$file" "$output_dir"
    fi
done

It’s a small change, but makes my life easier as I can run my script multiple times without needing to ensure that I’ve deleted any the source files for files that I’ve already transcoded.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK