Last active
October 6, 2018 03:57
-
-
Save photonxp/2d718c7732a2acb1508e7b67817efa4d to your computer and use it in GitHub Desktop.
Make the job of renaming files in the shell a little bit easier
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Features: | |
# Renaming file or files by batch with the shell script. | |
# Rename by multiple pairs of file names. | |
# Use the `mv` command along with `grep` etc. underlyingly. | |
# A rather simplified alternative to the `rename` shipped by some linux systems. | |
# Usage: | |
# 1. Rename a file by one pair of file names: | |
# ./rename_files.bash f1_name f2_name | |
# ./rename_files.bash ./dir_old ./dir_new | |
# f1_name could be in the format of: | |
# ./old_fname.txt or old_fname.txt | |
# ./old_dirname or old_dirname | |
# ~/old_dirname | |
# /path/to/old_dir | |
# f2_name should be the file/dir name that would be changed to | |
# and shouldn't include the upper level parent path | |
# 2. Rename files by multiple pairs of file names: | |
# ./rename_files.bash "f1_old1 f1_old2 .." "f2_new1 f2_new2 .." | |
# The number of f1 names should be the same as f2 names: | |
# e.g. ./rename_files.bash "./fname1.txt ~/dirname1" "fname2.txt dirname2" | |
# ./rename_files.bash "dirname1 /path/to/dir1" "dirname2 dir2" | |
# ./rename_files.bash "./{dirA1,dirB1}" "dirA2 dirB2" | |
# ./rename_files.bash "./{dirA1,dirB1} c1" "dirA2 dirB2 c2" | |
# ####test_rename_files.bash: | |
# #!/bin/bash | |
# | |
# # Test the usage of rename_files.bash | |
# # Operation on some files would fail on purpose | |
# # to show failure cases | |
# | |
# echo "Start test =============================" | |
# # | |
# if [[ -e ./test9 && "-o" != "$1" ]] | |
# then | |
# echo "Dir test9 existed. Quit." | |
# exit 1 | |
# fi | |
# # | |
# rm -r ./test9 | |
# mkdir -p ./test9/dir1 | |
# touch ./test9/t.old | |
# | |
# ./rename_files.bash "./test9/a1 ./test9/{t.old,dir1}" "a2 t.new dir2" | |
# | |
echo "Start script =============================" | |
str_raw_paths_of_f1=$1 | |
#str_raw_paths_of_f1="t1 ~/s1 /path_to/m1/ ~/{a1,b1}" | |
str_names_of_f2=$2 | |
#str_names_of_f2="t2 s2 m2 a2 b2" | |
# Raw path format: ~/dir{1,2}/ | |
# expanded path format: /home/user/dir1/ /home/user/dir2/ | |
# fine path format: /home/user/dir1 /home/user/dir2 | |
expand_path(){ | |
# raw path format: ~/s1 /path/to/t1/ m1 ~/{s1,s2} | |
str_expanded_paths_of_f1=$(eval echo "$str_raw_paths_of_f1") | |
} | |
check_num_of_paths_and_names(){ | |
arr_expanded_paths_of_f1=($str_expanded_paths_of_f1) | |
arr_names_of_f2=($str_names_of_f2) | |
if [ ${#arr_expanded_paths_of_f1[@]} -ne ${#arr_names_of_f2[@]} ] | |
then | |
echo "Notice:: The number of old files and the number of new names" | |
echo "NOtice:: are not matched." | |
echo "Notice:: Exit." | |
exit 1 | |
fi | |
} | |
make_fine_path(){ | |
expanded_path=$1 | |
# remove trailing slash "/" in expanded_path | |
fine_path=${expanded_path%/} | |
} | |
make_path_vars_of_f1_f2_by_path_withslash(){ | |
f1_path="$1" | |
f2_name="$2" | |
f1_parent_path=${f1_path%/*} | |
f2_path=$f1_parent_path/$f2_name | |
} | |
make_path_vars_of_f1_f2_by_path_without_slash(){ | |
# path is like a.txt | |
f1_path="$1" | |
f2_path=$f2_name | |
f1_parent_path="." | |
} | |
make_path_vars_of_f1_f2(){ | |
expanded_f1_path=$1 | |
f2_name=$2 | |
make_fine_path "$expanded_f1_path" | |
# arr cmd is usually easier than str cmd | |
# and safer than `eval` | |
# grep doesn't work with printf and pipe in arr command mode | |
# So use the command line in the shell | |
printf "$fine_path" | grep -q '/' | |
if [ 0 -eq $? ] | |
then | |
make_path_vars_of_f1_f2_by_path_withslash "$fine_path" "$f2_name" | |
else | |
make_path_vars_of_f1_f2_by_path_without_slash "$fine_path" "$f2_name" | |
fi | |
} | |
mv_files_by_arr_path_vars_of_f1_f2(){ | |
length=${#arr_names_of_f2[@]} | |
for ((i=0; $i<$length; i++)) | |
do | |
echo $i | |
expanded_f1_path=${arr_expanded_paths_of_f1[$i]} | |
f2_name=${arr_names_of_f2[$i]} | |
make_path_vars_of_f1_f2 "$expanded_f1_path" "$f2_name" | |
arr_paths_of_f1[$i]="$f1_path" | |
arr_paths_of_f2[$i]="$f2_path" | |
mv_cmd="mv $f1_path $f2_path" | |
printf "$mv_cmd \n" | |
$mv_cmd | |
done | |
# echo "arr_paths_of_f1:" ${arr_paths_of_f1[@]} | |
} | |
main(){ | |
expand_path | |
check_num_of_paths_and_names | |
mv_files_by_arr_path_vars_of_f1_f2 | |
} | |
################################# | |
main |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Test the usage of rename_files.bash | |
# Operation on some files would fail on purpose | |
# to show failure cases | |
echo "Start test =============================" | |
# | |
if [[ -e ./test9 && "-o" != "$1" ]] | |
then | |
echo "Dir test9 existed. Quit." | |
exit 1 | |
fi | |
# | |
rm -r ./test9 | |
mkdir -p ./test9/dir1 | |
touch ./test9/t.old | |
./rename_files.bash "./test9/a1 ./test9/{t.old,dir1}" "a2 t.new dir2" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment