Вставить символ в пакетное переименование папки

2

У меня есть папка, которая содержит несколько сотен тысяч файлов, названных как «ABC 123456». Мне нужно добавить тире после двух блоков текста, как это "ABC - 123456". Покидая место в конце.

Automator не предлагает метод для подсчета 4 символов и вставки нового тире и пробела.

У меня есть эта терминальная команда, и я с ней возился.

for file in *.txt
do
  echo mv "$file" **"$file" count 3 "- "**
done

Кто-нибудь знает Applescript или может помочь с командой терминала, которая поможет мне переименовать файлы?

пользователь-44651
источник

Ответы:

3

Сам вопрос тоже не точный, потому что ФП говорит о:

  • имена файлов вроде ABC 123456(без расширения), но в примере кода используется *.txtрасширение
  • добавить тире между двумя блоками (например, где находится пробел), как ABC - 123456, но в следующем, counting to 4и count 3, например, не совсем ясно, что скрипт должен делать, например, если найти ABCD 12илиAB 345
  • Кроме того, хочу сохранить конечный пробел, что странно - но хорошо;)

Задача делится на 3 отдельные части:

  1. выбор правильных файлов для переименования
  2. подготовка нового имени файла, замена / добавление символов в старое
  3. «физическое» переименование

Объявление "Выбор правильных файлов". Выбор файлов может быть сделан некоторыми внешними утилитами, например, findкомандой. Основными преимуществами findявляются:

  • он может искать файлы рекурсивно в подкаталогах тоже
  • можно точнее выбрать нужные файлы, например исключить каталоги, выбрать файлы по времени или размеру и так далее. (проверьте из терминала man find.)

Объявление "подготовить новое имя". Это может быть сделано внешними программами, такими как sedили awkлюбая другая программа, которая может манипулировать текстом в сценариях оболочки, или это может быть сделано (в некоторых простых случаях, таких как это) с помощью bashсамого себя - и возможно сохранить выполнение одной дорогой команды. (для тысяч файлов это имеет значение).

Последующий:

${file/ /-}

заменяет (заменяет) один пробел ( / /часть) тире ( /-). Так что можно написать

mv "$file" "${file/ /-}"

и сохранить sedисполнение.

Таким образом, одним из альтернативных решений может быть , например, следующее:

#!/bin/bash
while IFS= read -r -d $'\0' filename
do
    newfilename="${filename/ /-}"
    [[ "$filename" != "$newfilename" ]] && echo mv -i "$filename" "$newfilename"
done < <(find . -maxdepth 1 -type f -iname "* *.jpg" -print0)

Гробница предназначена для СУХОГО ЗАПУСКА - она ​​только покажет, что будет сделано, для реального выполнения удалите echo.

Распад:

  • выбрав нужные файлы для переименования: find . -maxdepth 1 -type f -iname "* *.jpg" -print0найдет все

    • что только в текущем каталоге ( -maxdepth 1)
    • и они простые файлы ( -type f)
    • и их имя совпадает (что угодно) (пробел) (что угодно) .jpg без учета регистра - например, имя должно содержать пробел
    • поставьте имена файлов как завершенные нулем , так что их имя также может безопасно содержать символ новой строки. ( -print0)
  • цикл while IFS= read -r -d $'\0' filename; do ... done < <( )

    • читает вывод из вышеуказанной findкоманды
    • где имена файлов заканчиваются нулем ( -d $'\0')
    • игнорировать любые экранированные символы ( -r) / расширенная тема - здесь объяснять не нужно /
    • что IFS= предотвращает Обрезка начальные и конечные пробелы из имени файла (также, немного сложная тема)
  • готовит новое имя файла newfilename="${filename/ /-}"

    • делается bashвнутренне (без выполнения внешней команды).
    • если хотите сохранить задний интервал после использования тире ${filename/ /- }
  • фактическое переименование выполняется mvкомандой (см. man mvиз терминала), где

    • -iчто будет спрашивать пользователя , если здесь уже имеется файл с новым именем (не отменяют его)
  • и mvвыполняется только тогда, когда newfilenameотличается отfilename [[ "$filename" != "$newfilename" ]]

Вышеупомянутое решение в основном подвержено ошибкам, но оно все еще не очень эффективно, потому что для сотен тысяч файлов mvкоманда будет выполняться в сотни тысяч раз . Решением может быть: использование некоторой утилиты, которая может прочитать имена файлов и выполнить переименование, не выполняя mvкоманду N-раз. Например, «большая пушка» системных администраторов «perl», как:

find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
    perl -0nle '$n=$_; $n=~s/ /-/; rename $_,$n unless($_ eq $n || -e $n)'

что будет переименовывать все файлы, что выводит findв одном исполнении - например, намного быстрее, чем тысячи mvвыполнений.

Тестирование Tor (DRY RUN) использует следующее:

find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
    perl -0nle '$n=$_; $n=~s/ /-/; print qq{old:$_ new:$n\n} unless($_ eq $n || -e $n)' #print instead of the rename

PS: Perl достаточно мощный, чтобы обрабатывать все сам, например. команда find тоже, но это более сложная тема ...

PS2: мой английский намного хуже моего bash, так что кто-то может отредактировать этот пост для добавления / исправления вещей ..;)

jm666
источник
2

Если ваши имена файлов «ABC 123456» с одним пробелом между первыми 3 и следующими, то вы пытаетесь заменить пробел символом (или тире или чем-то), чтобы он выглядел как ABC-123456.

Я нашел эту статью, которая объясняет, как это сделать.

Пример:

Обратите внимание, что следующая команда заменит пробелы только дефисами. Если вам нужна другая замена, вам придется соответственно изменить команду

for i in *.JPG; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done

Другие:

Если вы хотите использовать подчеркивание или любой другой символ вместо дефиса, вы просто переключите s, ,-,gчасть вышеуказанной команды на s, ,_,g.

Для того, чтобы увидеть эту статью .

Вот тест на MBA 10.9.5 (я использовал файл ABC 123456.png) и поместил его в новую папку. Чем я сделал компакт-диск в этот каталог в терминале и запустить

for i in *.png; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done

Результат, он прекрасно работает (переименовывает файл)

Как это работает ?, он заменит пробел в имени файла для всех файлов * .png в этой папке, поэтому сначала убедитесь, что он находится в нужной папке.

переименованный

Ruskes
источник