Last active
October 11, 2018 02:31
-
-
Save photonxp/2cee7fc6e84fe457bc1c3a5744cc7118 to your computer and use it in GitHub Desktop.
Rename pairs of link files in the shell. Rename by multiple pairs of link file names.
This file contains 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 | |
# The bubbles in the asset markets | |
# are equivalent to various taxes, | |
# payed by each of us in the long term, | |
# whether a winner or loser in the game. | |
# Features: | |
# Change a pair of link files | |
# from | |
# link1.old -> target1.old | |
# to | |
# link1.new -> target1.new | |
# Rename by multiple pairs of link file names | |
# A lightweight alternative to other heavy tools. | |
# Dependency: | |
# The `realpath` package is required | |
# Use the commands of `mv`,`ln`,`rm` etc. underlyingly. | |
# Usage: | |
# Link and target files should have the same new name, | |
# but not necessarily the same old name. | |
# 1. Rename link/target by one pair of file names: | |
# ./rename_linkets.bash link_old_path new_name | |
# The link_old_path could be in the format of: | |
# ./old_link.yy or old_link.yy | |
# ./old_link or old_link | |
# ~/old_link | |
# /path/to/old_link | |
# The new_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_linkets.bash "old_link1 old_link2 .." "new_name1 new_name2 .." | |
# The number of old_link files should be the same as new names: | |
# ./rename_linkets.bash "./{link1,link2}" "new_name1 new_name2" | |
# ./rename_linkets.bash "./{link1,link2} c1" "new_name1 new_name2 c2" | |
# Linket: | |
# A pair of files for linking, that work in the form of: | |
# Link file -> Target file | |
# #!/bin/bash | |
# | |
# # Test the usage of rename_linkets.bash | |
# # Operation on some files would fail on purpose | |
# # to show failure cases | |
# | |
# # use ./test_rename_linkets.bash -o | |
# # to override the check on the test dir/files | |
# | |
# echo_start(){ | |
# echo "Start test $1 =============================" | |
# } | |
# | |
# init(){ | |
# echo_start "$1" | |
# rm -r ./test9 | |
# mkdir -p ./test9/dir1 ./test9/dir2 | |
# } | |
# | |
# run_tests(){ | |
# if [[ -e ./test9 && "-o" != "$option" ]] | |
# then | |
# echo "Dir test9 existed. Quit." | |
# exit 1 | |
# fi | |
# | |
# for test in "$@" | |
# do | |
# init "$test" | |
# $test | |
# done | |
# } | |
# | |
# test1(){ | |
# touch ./test9/b.o | |
# touch ./test9/dir2/r.o | |
# | |
# ln -s ../dir2/t.o ./test9/dir1/t.o | |
# ln -s "../dir2/r.o" ./test9/dir1/r.o | |
# | |
# ./rename_linkets.bash "./test9/a.o test9/b.o ./test9/dir1/{t.o,r.o}" "a.n b.n t.n r.n" | |
# } | |
# | |
# test2(){ | |
# if [ "-o" != "$option" ] | |
# then | |
# for f in `echo "u.o u.n"` | |
# do | |
# echo "File $f existed. Quit." | |
# exit 1 | |
# done | |
# fi | |
# | |
# rm u.o u.n ./test9/u.o | |
# touch ./test9/u.o | |
# ln -s ./test9/u.o u.o | |
# ./rename_linkets.bash u.o u.n | |
# } | |
# | |
# test3(){ | |
# # test dangerous path | |
# touch ./test9/dir2/dg.o | |
# ln -s ../dir2/dg.o ./test9/dir1/dg.o | |
# ./rename_linkets.bash ./test9/dir1/dg.o dg.n | |
# } | |
# | |
# option="$1" | |
# | |
# #run_tests test1 | |
# #run_tests test2 | |
# #run_tests test3 | |
# run_tests test1 test2 | |
# | |
echo "Start script ----------------------" | |
# f1: old link file or old target file | |
# of the linket (link pair) | |
# f2: new link file or new target file | |
# of the linket (link pair) | |
# Linket: a pair of files for linking, that work in the form of: | |
# Link file -> Target file | |
# Raw path format: ~/dir{1,2}/ | |
# expanded path format: /home/user/dir1/ /home/user/dir2/ | |
# fine path format: /home/user/dir1 /home/user/dir2 | |
check_dependency(){ | |
rslt=$(realpath --version) | |
bin_name="${rslt:0:8}" | |
if [ "realpath" != "$bin_name" ] | |
then | |
echo "ERR:: Require the package of realpath, but realpath is not found." | |
echo " To install realpath, run the command of:" | |
echo " sudo apt-get update && sudo apt-get install realpath" | |
echo " Exit." | |
exit 1 | |
fi | |
} | |
expand_path(){ | |
# raw path format: ~/s1 /y/tt1/ t1 ~/{s1,s2} | |
str_expanded_paths_of_f1="$(eval echo $str_raw_paths_of_f1)" | |
#echo "str_expanded_paths_of_f1:" $str_expanded_paths_of_f1 | |
} | |
check_nums_of_path_and_name(){ | |
arr_expanded_paths_of_f1=($str_expanded_paths_of_f1) | |
arr_names_of_f2=($str_names_of_f2) | |
#echo "arr_expanded_paths_of_f1: ${arr_expanded_paths_of_f1[@]}" | |
if [ ${#arr_expanded_paths_of_f1[@]} -ne ${#arr_names_of_f2[@]} ] | |
then | |
echo "ERR:: The number of old files and the number of new names" | |
echo "ERR:: are not matched." | |
exit 1 | |
fi | |
} | |
check_arg_nums(){ | |
length_arglist_raw=$# | |
if [ 2 -gt $length_arglist_raw ] | |
then | |
echo "ERR:: Lacking operand for $0" | |
exit 1 | |
fi | |
check_nums_of_path_and_name | |
} | |
check_if_link_file_exist(){ | |
expanded_f1_path="$1" | |
# tricky test conditions here. | |
if [ -h "$expanded_f1_path" ] | |
then | |
# -a not work here, use -e | |
if [ ! -e "$expanded_f1_path" ] | |
then | |
target_path=$(readlink -m "$expanded_f1_path") | |
echo "NOTICE:: Broken link: $expanded_f1_path -> $target_path" | |
return 1 | |
fi | |
return 0 | |
fi | |
if [ ! -f "$expanded_f1_path" ] | |
then | |
echo "NOTICE:: Couldn' find linket link file for path: $expanded_f1_path" | |
return 1 | |
fi | |
if [ -f "$expanded_f1_path" ] | |
then | |
echo "NOTICE:: Not a linket link file, but a regular file: $expanded_f1_path" | |
return 1 | |
fi | |
} | |
check_if_is_dangerous_path(){ | |
fpath="$1" | |
ftype="$2" | |
# 1 means "no danger", 0 means "has danger" | |
path_has_danger=1 | |
dangerous_path_list=("/") | |
#dangerous_path_list=("~/data_mnt/_____data/linux/command_tool/mv/rename_linkets/test9/dir1/dg.o") | |
for dangerous_path in "${dangerous_path_list[@]}" | |
do | |
if [ "$dangerous_path" == "$fpath" ] | |
then | |
path_has_danger=0 | |
info="$2 old path has dangerous path "$dangerous_path" in : $fpath" | |
echo "ERR:: $info. Exit." | |
exit 1 | |
fi | |
done | |
} | |
make_f2path_by_f1path_f2name(){ | |
# make f2path for either link or target | |
# by their f1path and new name | |
f1_path=$1 | |
f2_name=$2 | |
f1_parent_path=${f1_path%/*} | |
f2_path=$f1_parent_path/$f2_name | |
} | |
make_paths_of_linket_link(){ | |
make_f2path_by_f1path_f2name "$f1_path_of_link" "$f2_name" | |
f2_path_of_link=$f2_path | |
ftype="Linket-link" | |
check_if_is_dangerous_path "$f1_path_of_link" "$ftype" | |
} | |
make_paths_of_linket_target(){ | |
f1_path_of_target=$(realpath "$f1_path_of_link") | |
make_f2path_by_f1path_f2name "$f1_path_of_target" "$f2_name" | |
f2_path_of_target=$f2_path | |
ftype="Linket-target" | |
check_if_is_dangerous_path "$f2_path_of_target" "$ftype" | |
} | |
make_paths_of_linket(){ | |
# Linket: a pair of files for linking, that work in the form of: | |
# Link file -> Target file | |
f1_path_of_link=$(realpath -s "$1") | |
f2_name=$2 | |
make_paths_of_linket_link | |
make_paths_of_linket_target | |
} | |
make_paths_of_linket_in_oneloop(){ | |
make_paths_of_linket "$expanded_f1_path" "$f2_name" | |
# keey the arr for future debug info | |
arr_f1_paths_of_link[$i]=$f1_path_of_link | |
arr_f2_paths_of_link[$i]=$f2_path_of_link | |
arr_f1_paths_of_target[$i]=$f1_path_of_target | |
arr_f2_paths_of_target[$i]=$f2_path_of_target | |
} | |
mv_target_file(){ | |
cmd="mv $f1_path_of_target $f2_path_of_target" | |
} | |
ln_new_target_file(){ | |
cmd="ln -s $f2_path_of_target $f2_path_of_link" | |
} | |
rm_old_link_file(){ | |
cmd="rm $f1_path_of_link" | |
} | |
do_linket_by_steps(){ | |
do_file_steps=("mv_target_file" "ln_new_target_file" "rm_old_link_file") | |
for make_cmd_by_step in "${do_file_steps[@]}" | |
do | |
$make_cmd_by_step | |
printf "$cmd \n" | |
if ! $cmd | |
then | |
echo "NOTICE:: Operation failed." | |
return 1 | |
fi | |
done | |
} | |
rename_linkets(){ | |
length=${#arr_names_of_f2[@]} | |
for (( i=0; $i<$length; i++ )) | |
do | |
echo $i | |
f2_name=${arr_names_of_f2[$i]} | |
expanded_f1_path="${arr_expanded_paths_of_f1[$i]}" | |
check_if_link_file_exist "$expanded_f1_path" | |
if [ 0 -ne $? ] | |
then | |
continue | |
fi | |
make_paths_of_linket_in_oneloop | |
do_linket_by_steps | |
done | |
#echo "arr_f1_paths_of_target:" ${arr_f1_paths_of_target[@]} | |
} | |
main(){ | |
check_dependency | |
str_raw_paths_of_f1="$1" | |
str_names_of_f2="$2" | |
expand_path | |
check_arg_nums "$@" | |
rename_linkets | |
} | |
#################################### | |
main "$@" |
This file contains 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_linkets.bash | |
# Operation on some files would fail on purpose | |
# to show failure cases | |
# use ./test_rename_linkets.bash -o | |
# to override the check on the test dir/files | |
echo_start(){ | |
echo "Start test $1 =============================" | |
} | |
init(){ | |
echo_start "$1" | |
rm -r ./test9 | |
mkdir -p ./test9/dir1 ./test9/dir2 | |
} | |
run_tests(){ | |
if [[ -e ./test9 && "-o" != "$option" ]] | |
then | |
echo "Dir test9 existed. Quit." | |
exit 1 | |
fi | |
for test in "$@" | |
do | |
init "$test" | |
$test | |
done | |
} | |
test1(){ | |
touch ./test9/b.o | |
touch ./test9/dir2/r.o | |
ln -s ../dir2/t.o ./test9/dir1/t.o | |
ln -s "../dir2/r.o" ./test9/dir1/r.o | |
./rename_linkets.bash "./test9/a.o test9/b.o ./test9/dir1/{t.o,r.o}" "a.n b.n t.n r.n" | |
} | |
test2(){ | |
if [ "-o" != "$option" ] | |
then | |
for f in `echo "u.o u.n"` | |
do | |
echo "File $f existed. Quit." | |
exit 1 | |
done | |
fi | |
rm u.o u.n ./test9/u.o | |
touch ./test9/u.o | |
ln -s ./test9/u.o u.o | |
./rename_linkets.bash u.o u.n | |
} | |
test3(){ | |
# test dangerous path | |
touch ./test9/dir2/dg.o | |
ln -s ../dir2/dg.o ./test9/dir1/dg.o | |
./rename_linkets.bash ./test9/dir1/dg.o dg.n | |
} | |
option="$1" | |
#run_tests test1 | |
#run_tests test2 | |
#run_tests test3 | |
run_tests test1 test2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment