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

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

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

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

 file.csv_suffix 

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

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, который не исключает каталоги.

  • Формат вывода xargs
  • xargs: слишком длинная строка аргументов
  • Как выполнить команду несколько раз с разными аргументами?
  • Пустые строки при выполнении «grep | xargs "в" find -exec "
  • tcpdump несколько pcaps с xargs
  • xargs игнорирует второй параметр скрипта
  • Обработка временных меток вывода tcpdump в режиме реального времени
  • Перемещение файлов с помощью find + xargs: target не является каталогом?
  • Как уменьшить количество исполнений с помощью xargs -I
  • Как копировать рекурсивно все файлы не старше 1 дня?
  • Команда xargs приводит к sed:;: Нет такого файла или каталога
  • Interesting Posts

    Изменить таблицу разделов с помощью GParted

    Можно ли добавить сервисное меню KDE / dolphin для определенного расширения файла?

    Изменение имени сервера в файле OpenVPN с помощью sed

    Прозрачный прокси-сервер HTTPS Squid с родительским потоком

    Подробное профилирование для каждого процесса

    Как я могу сделать несколько символических ссылок для нескольких каталогов, удобно

    Как мне заставить systemd запускать скрипт монтирования ZFS, прежде чем делать что-нибудь еще?

    Установка последней r-базы из r-проекта

    разрешить webalizer в selinux (centos)

    Wget – получение рекурсивных URL-адресов из списка URL-адресов

    Проверить переменную – массив в Bourne как shell?

    Открыть tar-файл, который заканчивается на .b

    uniq и bash для цикла, не записывающего в stdout перед закрытием stdin (для системы уведомлений посетителей в одной строке)

    как прикасаться к файлам, таким как report-07/05/13

    Мариадб заменил MySQL на Yum Ugrade

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