Intereting Posts
Почему ln -s скопировал файл, а не связал его? Как создать моментальный снимок только для чтения в btrfs? Файл Bash: нет такого файла или каталога Копирование содержимого emacs через буфер обмена в терминальном приложении копирует неожиданные вкладки для некоторых пространств Установка гостевых дополнений VBox при отсутствии X-сервера Как извлечь строку на основе соответствия регулярных выражений из неформатированного файла цифровая клавиатура не работает на ноутбуке Как добавить хэш файла в файл Создание символической ссылки в / bin автоматически создает вторую ссылку в / usr / bin и какая команда выбирает / usr / bin dig vs nslookup Docker не смог найти доступный, неперекрывающийся пул адресов IPv4 Почему Wheezy не регистрируется после удаления pavucontrol Bash в php exec на веб-странице не окрашивает файлы png и mp3 в Linux Команды сценария bash, разделенные пробелом Не удается разрешить имя хоста на сервере Linux

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

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

Все можно сделать в выражении 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!