Переименовывать файлы, а не каталоги

Я хочу переименовать все файлы в нижний регистр в каталог без переименования подкаталогов. Я знаю функцию переименования, но она переименовывает файлы и подкаталоги, которые нежелательны. Вы можете помочь?

5 Solutions collect form web for “Переименовывать файлы, а не каталоги”

Все можно сделать в выражении perl.

Используйте -f , обычный тест файла, чтобы только обычные файлы (не каталоги) были переименованы.

Это работает:

 rename 'y/AZ/az/ if -f;' ./* 

(Использование ./* вместо * гарантирует, что имена файлов не будут интерпретироваться как параметры, даже если имя файла начинается с тире (-).

С zsh :

 autoload zmv # best in ~/.zshrc zmv '*(#q^/)' '${(L)f}' 

Переименовывать файлы любого типа, кроме каталога. Или:

 zmv '*(#q.)' '${(L)f}' 

Переименование только обычных файлов. Чтобы также включить скрытые файлы, добавьте квалификатор D glob.

Пример (с использованием -n для сухого хода):

 $ ls -alQF total 132 drwxr-xr-x 3 stephane stephane 4096 Oct 27 09:11 "."/ drwxr-xr-x 533 stephane stephane 122880 Oct 27 09:11 ".."/ drwxr-xr-x 2 stephane stephane 4096 Oct 27 09:07 "DIR"/ lrwxrwxrwx 1 stephane stephane 3 Oct 27 09:07 "DIR-LINK" -> "DIR"/ prw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "FIFO"| -rw-r--r-- 1 stephane stephane 0 Oct 27 09:11 ".HIDDEN FILE" -rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "HOLIDAYS IN МОСВА\nRED SQUARE.JPG" lrwxrwxrwx 1 stephane stephane 23 Oct 27 09:08 "MY-RÉSUMÉ.PDF" -> "STÉPHANE'S RÉSUMÉ.PDF" -rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "--READ-ME--.TXT" srwxr-xr-x 1 stephane stephane 0 Oct 27 09:09 "SOCKET"= -rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "STÉPHANE'S RÉSUMÉ.PDF" $ zmv -n '*(#q^/)' '${(L)f}' mv -- DIR-LINK dir-link mv -- FIFO fifo mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg mv -- MY-RÉSUMÉ.PDF my-résumé.pdf mv -- --READ-ME--.TXT --read-me--.txt mv -- SOCKET socket mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf $ zmv -n '*(#q.)' '${(L)f}' mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg mv -- --READ-ME--.TXT --read-me--.txt mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf $ zmv -n '*(#qD.)' '${(L)f}' mv -- .HIDDEN\ FILE .hidden\ file mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg mv -- --READ-ME--.TXT --read-me--.txt mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf 

Посмотрите, как некоторые из них сломают некоторые символические ссылки.

Преобразование в нижний регистр может быть выполнено путем набора var в нижний регистр.

EDIT: Замените решение с помощью find для решения с for .

Сначала я попробовал решение с помощью find , надеясь найти файлы только с -type f .
Кажется, что это хорошо работает:
Я использовал -maxdepth 1 поэтому я ничего не менял в других папках (что было бы немного сложнее, если имя каталога в верхнем регистре).
Это привело к

 typeset -l smallfile echo "Find solution looks OK but read more..." find .-maxdepth 1 -type f| while read file; do smallfile="${file}" mv "${file}" "${smallfile}" done 

Я думал, что эта конструкция будет обрабатывать имена файлов с пробелами правильно, что я тестировал с именами файлов, такими как «Файл с пробелами». @Chazelas правильно прокомментировал, что решение терпит неудачу с именами файлов, заканчивающимися пробелом («Слишком плохо»). В другом комментарии объясняется, как исправить команду find find: find ... -print0 | while IFS= read -rd '' file find ... -print0 | while IFS= read -rd '' file (ваша find должна поддерживать print0 , в основном bash и zsh ).
Поскольку я уже использую цикл, я могу просто использовать test чтобы увидеть текущий элемент (заданный * ), является обычным файлом.
Я нашел решение с простым for-loop и покажу его здесь, включая мой тестовый код.

 #!/bin/bash clear rm -rf testfiles 2>/dev/null mkdir -p testfiles/SomeDir #2>/dev/null mkdir testfiles/"Crazy Dir" 2>/dev/null touch testfiles/Aha testfiles/"File with Spaces" testfiles/"End with space " ls -lQ testfiles echo =================== typeset -l smallfile for file in testfiles/* # Stack's formatting thinks /* starts comment, so I close that here: */ do if [ -f "${file}" ]; then smallfile="${file}" # echo mv "${file}" "${smallfile}" mv "${file}" "${smallfile}" fi done echo =================== ls -lQ testfiles 

Для текущего testdir/ удалить testdir/ из цикла for.

Можешь попробовать

 cd directory ; rename 'y/AZ/az/' $(ls -p | grep -v /$) ; cd - 

Но лучше использовать find

 cd directory ; find * -prune -type f -exec rename 'y/AZ/az/' {} + ; cd - 

Этот oneliner решит это:

 find path-to-search -depth -type f -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \; 

Cya!

  • Переименование нескольких файлов gzips и удаление более 10 дней
  • проверка наибольшего количества определенной папки
  • Извлеките путь к каталогу, содержащий файл с соответствующей строкой
  • Изменение владельца файла на основе предыдущего владельца
  • добавление программ в путь
  • Непрерывный каталог резервных копий на USB-накопителе
  • Права на наследование файлов каталога, на которые он скопирован?
  • Как создать несколько файлов в текущем каталоге в bash?
  • Удаление числовых файлов с более чем n знаками после запятой
  • Linux не видит файл до тех пор, пока я не перейду в этот каталог
  • Я хочу создать псевдоним для редактирования файла с помощью nano. Является ли это возможным?
  • Linux и Unix - лучшая ОС в мире.