l имеют приблизительно 100 каталогов, таких как:
Каждый из этих каталогов содержит ряд файлов.
l хотел бы добавить название префикса каталога к именам файлов его файлов.
Например:
writing :
0ZPQl5QUvo0_000202_000212.mp4
AFV8x8ezN8g_000016_000026.mp4
-HutuMqTAPw_000275_000285.mp4
qtvsw6h3yQo_000228_000238.mp4
Ub0rc6U6nfI_000100_000110.mp4
становится:
writing :
writing_0ZPQl5QUvo0_000202_000212.mp4
writing_AFV8x8ezN8g_000016_000026.mp4
writing_-HutuMqTAPw_000275_000285.mp4
writing_qtvsw6h3yQo_000228_000238.mp4
writing_Ub0rc6U6nfI_000100_000110.mp4
Как я могу сделать это?
Вот немного улучшенная версия Вашего сценария - основные отличия
использование шарика оболочки *
вместо $(ls)
- посмотрите Ловушку Bash № 1
заключение в кавычки любых переменных расширений (позволяет имена файлов с пробелом или другими забавными символами - видит Ловушку Bash № 2),
маркировка конца опций к mv
использование --
Расширение GNU - это позволяет ему обработать имена файлов, которые запускаются с дефисов также
Так
for d in *; do
[[ -d "$d" ]] && cd "$d" || continue
for f in *.mp4; do
echo mv -v -- "${f}" "${d}_${f}"
done
cd -
done
Или более портативно можно циклично выполниться ./*.mp4
для защиты от ведущих дефисов - но затем необходимо снять изоляцию с него во время mv
for d in *; do
[ -d "$d" ] && cd "$d" || continue
for f in ./*.mp4; do
echo mv -v "${f}" "${d}_${f#./}"
done
cd -
done
В любом случае удалите echo
(и -v
если Вы желаете), после того как Вы уверены, что это работает, как Вы ожидаете.
Проблема решена с помощью следующего сценария:
for i in $(ls); do
if [ -d $i ]; then
fname=${i##*/}
echo $fname
cd $i
for z in *.mp4; do
echo $z
cp $z ${fname}_${z}
rm $z
done
cd ..
fi
done
Принятие Вас находится в каталоге, содержащем все эти каталоги dancing
, writing
, и т.д., команда
for folder in $(find -mindepth 1 -type d); do
cd $folder
PRE=${folder#./}
for file in *; do
mv "$file" "${PRE}_$file"
done
cd ..
done
достигнет того, что Вы хотите. Я протестировал его, и это работало, даже когда имена файлов содержали пробелы или новые строки. Это не работало с такими символами на имена папок, тем не менее, например, walking slowly
.
Править: Предыдущий код не обрабатывает пробелы или новые строки на имена папок. Для покрытия этого используйте измененный код
for folder in *; do
if [ -d "$folder" ]; then
cd "$folder"
PRE=${folder#./}
for file in *; do
mv "$file" "${PRE}_$file"
done
cd ..
fi
done
Редактирование 2: Если имя файла запускается с a -
(тире), команда может интерпретировать его как опцию. Для контакта с продвижением тире вставьте a --
между mv
команда и ее аргументы. Это говорит mv
прекратить сканировать для опций.
Таким образом, заключительный код
for folder in *; do
if [ -d "$folder" ]; then
cd "$folder"
for file in *; do
mv -- "$file" "${folder}_$file"
done
cd ..
fi
done
Использовать find
и prename
:
find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'
Удалите -n
опция на самом деле переименовать файлы и не только распечатать, как файлы были бы переименованы.