Добавить суффикс ко всем файлам без определенного расширения и сохранить расширение файла

У меня есть каталог, в котором есть .zip файлы и другие файлы (все файлы имеют расширение), и я хочу добавить суффикс ко всем файлам без расширения .zip . Я могу выбрать суффикс и поместить его в переменную $suffix , поэтому я попробовал следующий код:

ls -I "*.zip"| xargs -I {} mv {} {}_"$suffix"

Здесь перечислены все файлы без .zip и близко (но неправильно). Он неверно дает следующие результаты в file.csv :

 file.csv_suffix 

Я хочу file_suffix.csv – как я могу изменить свой код, чтобы сохранить расширение в файле?

  • Изменить каталог на основе вывода конвейера
  • Поиск строки в каталоге. Получить вывод без имени файла.
  • Почему имена файлов трубопроводов в VIM прерываются, когда я возвращаюсь в оболочку?
  • Выполнение нескольких команд с помощью xargs
  • Как найти и скопировать файлы на основе расширения?
  • Расшифровывать файлы, зашифрованные с помощью gpg, с помощью xargs
  • рекурсивно chmod
  • Почему xargs заставляет apt-get прерываться?
  • 5 Solutions collect form web for “Добавить суффикс ко всем файлам без определенного расширения и сохранить расширение файла”

    найти + bash :

     export suffix="test" 

    a ) с действием find -exec :

    find your_folder -type f ! -name "*.zip" -exec bash -c 'f=$1; if [[ "$f" =~ .*\.[^.]*$ ]]; then ext=".${f##*\.}"; else ext=""; fi; mv "$f" "${f%.*}_$suffix$ext"' x {} \;


    b ) Или с байтом while:

     find your_folder/ -type f ! -name "*.zip" -print0 | while read -d $'\0' f; do if [[ "$f" =~ .*\.[^.]*$ ]]; then ext=".${f##*\.}" else ext="" fi mv "$f" "${f%.*}_$suffix$ext" done 

    Использование ls немного опасно. См. Почему * не * разбирать `ls`?

    Вам также придется выделить имя файла, иначе вы просто добавите $suffix до конца, как вы обнаружили.

    Здесь следует решение, использующее find , и одно без find .


     find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} + 

    Это найдет все обычные файлы или где-то под текущим каталогом, имена которых не заканчиваются на .zip .

    Затем будет вызываться следующий сценарий оболочки со списком этих файлов:

     suffix="$1" # the suffix is passed as the first command line argument shift # shift it off $@ for n; do # loop over the remaining names in $@ p=${n%.*} # get the prefix of the file path up to the last dot s=${n##*.} # get the extension of the file after the last dot # rename the file if there's not already a file with that same name [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s" done 

    Тестирование:

     $ touch file{1,2,3}.txt file{a,b,c}.zip $ ls file1.txt file2.txt file3.txt filea.zip fileb.zip filec.zip $ suffix="notZip" $ find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} + $ ls file1_notZip.txt file3_notZip.txt fileb.zip file2_notZip.txt filea.zip filec.zip 

    Сценарий оболочки выше можно запустить независимо от find если количество файлов не очень велико, и если вам не нужно переписывать в подкаталоги (только слегка измененные, чтобы пропустить имена без файлов):

     #!/bin/sh suffix="$1" # the suffix is passed as the first command line argument shift # shift it off $@ for n; do # loop over the remaining names in $@ [ ! -f "$n" ] && continue # skip names of things that are not regular files p=${n%.*} # get the prefix of the file path up to the last dot s=${n##*.} # get the extension of the file after the last dot # rename the file if there's not already a file with that same name [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s" done 

    С помощью bash вы запускаете это в файлах в каталоге, например:

     $ shopt -s extglob $ ./script.sh "notZip" !(*.zip) 

    С extglob оболочки extglob установленной в bash !(*.zip) будет соответствовать всем именам в текущем каталоге, который не заканчивается на .zip .

    В bash:

     shopt -s extglob suffix=yoursuffix for entry in !(*.zip) do [[ -f "$entry" ]] || continue base=${entry%.*} if [[ "$entry" =~ \. ]] then ext=${entry##*.} echo mv -- "$entry" "${base}_${suffix}.${ext}" else echo mv -- "$entry" "${base}_${suffix}" fi done 

    Удалите echo когда оно выглядит правильно.

    Тестовые случаи:

     touch a.zip b.zip foo bar file.csv a.file.csv 'test case' 'test case.csv' mkdir baz 

    Пример вывода:

     mv -- a.file.csv a.file_yoursuffix.csv mv -- bar bar_yoursuffix mv -- file.csv file_yoursuffix.csv mv -- foo foo_yoursuffix mv -- scr scr_yoursuffix mv -- test case test case_yoursuffix mv -- test case.csv test case_yoursuffix.csv 

    … пропустить каталог baz , но переименовать foo и bar соответственно.

      find <pathtodirectory> ! -name *.zip | awk -v suff=$suffix -F\. '{ print $1"_"suff"."$2 }' 

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

     find <pathtodirectory> ! -name *.zip | awk -v suff=$suffix -F\. '{ system("mv "$0" "$1"_"suff"."$2) }' 

    Обратите внимание, что есть риск внедрения команд с решением. Также обратите внимание, что решение зависит от всех файлов, имеющих имя файла структуры. Расширение, которое может быть или не быть.

     for f in `ls -I "*.zip" `; do mv $f `echo $f | cut -d '.' -f1`_suffix.`echo $f | cut -d '.' -f2` ; done ; 

    Другие интересные инструменты включают утилиты, такие как переименование

    Это интересный вопрос, но это также означает, что его, вероятно, уже много раз спрашивали . Примечание. Я сохранил файл op, который не исключает каталоги.

    Linux и Unix - лучшая ОС в мире.