41

Допустим, у меня есть каталог, полный файлов .md названных по-разному. Допустим, я хотел добавить "текст" в начале каждого имени файла. Например, файлы a.md , b.md и c.md станут test - a.md , test - b.md и test - c.md

Как бы я сделал это через командную строку?

7 ответов7

54

Однострочник, который можно легко набирать прямо с терминала:

for f in *.md; do mv "$f" "test - $f"; done

Или переписать в отдельных строках вместо точек с запятой:

for f in *.md
do
    mv "$f" "test - $f"
done

экспозиция

Синтаксис forsh):

for NAME [in WORDS ... ] ; do COMMANDS; done

Здесь наше NAME - f а WORDS - это все файлы в текущем каталоге, соответствующие *.md . Таким образом, переменная $f будет заменена на каждый файл, соответствующий *.md .

Итак, для a.md:

mv "$f" "test - $f"

становится

mv "a.md" "test - a.md"

Кавычки важны, потому что каждое имя файла $f может содержать пробелы. В противном случае mv думал бы, что каждое слово было отдельным файлом. Например, если бы не было кавычек, а есть файл с именем Foo Bar.md , он был бы переведен как:

mv Foo Bar.md test - Foo Bar.md

который не будет работать как задумано. Но, заключив $f в кавычки, имеет смысл:

mv "Foo Bar.md" "test - Foo Bar.md"

Принимая во внимание синтаксис for , вы также можете переименовать подмножество всех файлов *.md , назвав каждый явно:

for f in a.md b.md d.md; do mv "$f" "Test - $f"; done

Или используя расширение оболочки:

for f in {a,b,d}.md; do mv "$f" "Test - $f"; done
11

Если у вас есть prename ...

prename 's/^/test - /' *.md

Используя обычные команды оболочки:

for file in *.md; do
    mv "$file" "test - $file"
done
5

mmv 1, 2 также очень хороший инструмент для такой задачи, применительно к текущей работе, это было бы

mmv '*.md' 'test - #1.md'

Конечно, если вы хотите добавить «test -» только в a.md, b.md и c.md, но не в a1.md, что-то вроде

mmv '?.md' 'test - #1.md'

было бы более уместным.

Я действительно могу предложить это, особенно если у вас много таких проблем.

Если вы ищете графический интерфейс, попробуйте gprename.

4

Вместо использования цикла for, который не будет работать в пробелах, если вы не переопределите переменную IFS, я бы рекомендовал использовать цикл while в сочетании с find. Следующее будет работать при запуске из того же каталога, что и файлы

find . -maxdepth 1 -type f -name '*.md' | while read -r file; do
    file=$(basename $file)
    mv "$file" "test - $file"
done

там находится строка "basename", так что find будет печатать только имя файла - без компонентов пути, что может привести к прерыванию операции переименования.

0

Если у вас есть zsh вы можете использовать zmv:

autoload zmv
zmv -w '*' 'test - $1'

Вы можете проверить команду с:

zmv -wn '*' 'test - $1'
  • -n означает «пробежка», то есть показывает только то, что произойдет.
  • -w неявно ставит круглые скобки вокруг подстановочных знаков, заставляет работать обратные ссылки.
0

В bash добавление «Prepend text -» для всех файлов в папке:

for i in *; do mv "$i" "$(echo $i | sed 's/^/Prepend\ text\ \-\ /')"; done;
0

Я знаю, что уже поздно, но если кто-то ищет что-то подобное, у меня это сработало:

rename '' 'name -' *.md

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .