Взять пример:
/a/1/b/c/d/file.txt
/a/2/b/c/d/file.txt
Единственный надежный способ указать file.txt
и избежать конфликтов - встроить весь путь в новое имя файла, например,
/a/1/b/c/d/file.txt -> a_1_b_c_d_file.txt
/a/2/b/c/d/file.txt -> a_2_b_c_d_file.txt
Вы можете пропустить часть начала, если точно знаете, что она будет общей для всех файлов, например, если вы знаете, что все файлы находятся где-то под каталогом /a
выше:
/a/1/b/c/d/file.txt -> 1_b_c_d_file.txt
/a/2/b/c/d/file.txt -> 2_b_c_d_file.txt
Чтобы добиться этого для каждого файла:
# file="/path/to/filename.txt"
new_file="`echo \"$file\" | sed -e 's:^/::' -e 's:/:_:g'`"
# new_file -> path_to_filename.txt
Скажем, вы хотите сделать это рекурсивно в каталоге и его подкаталогах:
# dir = /a/b
( cd "$dir" && find . | sed -e 's:^\./::' | while read file ; do
new_file="`echo \"$file\" | sed -e 's:/:_:g'`"
echo "rename $dir/$file to $new_file"
done )
Выход:
rename /a/b/file.txt to file.txt
rename /a/b/c/file.txt to c_file.txt
rename /a/b/c/e/file.txt to c_e_file.txt
rename /a/b/d/e/file.txt to d_e_file.txt
...
Вышеприведенное легко переносимо и будет работать практически на любой системе Unix с любым вариантом sh
(включая bash
, ksh
и т. Д.)