These handy commands allow you to extract filenames and directory portions of the given paths. You could also use Parameter Expansion or
awk, etc for such purposes. The advantage is that these commands will also handle corner cases like trailing slashes and there are handy features like removing file extensions.
By default, the
basename command will remove the leading directory component from the given path argument. Any trailing slashes will be removed before determining the portion to be extracted.
$ basename /home/learnbyexample/example_files/scores.csv scores.csv # quote the arguments when needed $ basename 'path with spaces/report.log' report.log # one or more trailing slashes will not affect the output $ basename /home/learnbyexample/example_files/ example_files
If there's no leading directory component or if slash alone is the input, the argument will be returned as is after removing any trailing slashes.
$ basename filename.txt filename.txt $ basename / /
You can use the
-s option to remove a suffix from the filename. Usually used to remove the file extension.
$ basename -s'.csv' /home/learnbyexample/example_files/scores.csv scores $ basename -s'_2' final_report.txt_2 final_report.txt $ basename -s'.tar.gz' /backups/jan_2021.tar.gz jan_2021 $ basename -s'.txt' purchases.txt.txt purchases.txt # -s will be ignored if it would have resulted in empty output $ basename -s'report' /backups/report report
You can also pass the suffix to be removed after the path argument, but the
-s option is preferred as it makes the intention clearer and works for multiple path arguments.
$ basename example_files/scores.csv .csv scores
By default, the
dirname command removes the trailing path component (after removing any trailing slashes).
$ dirname /home/learnbyexample/example_files/scores.csv /home/learnbyexample/example_files # one or more trailing slashes will not affect the output $ dirname /home/learnbyexample/example_files/ /home/learnbyexample
dirname command accepts multiple path arguments by default. The
basename command requires
-s (which implies
-a) to work with multiple arguments.
$ basename -a /backups/jan_2021.tar.gz /home/learnbyexample/report.log jan_2021.tar.gz report.log # -a is implied when -s is used $ basename -s'.txt' logs/purchases.txt logs/report.txt purchases report $ dirname /home/learnbyexample/example_files/scores.csv ../report/backups/ /home/learnbyexample/example_files ../report
You can use shell features like command substitution to combine the effects of
# extract the second last path component $ basename $(dirname /home/learnbyexample/example_files/scores.csv) example_files
-z option if you want to use NUL character as the output path separator.
$ basename -zs'.txt' logs/purchases.txt logs/report.txt | cat -v purchases^@report^@ $ basename -z logs/purchases.txt | cat -v purchases.txt^@ $ dirname -z example_files/scores.csv ../report/backups/ | cat -v example_files^@../report^@