Linux: удалить расширения для нескольких файлов - PullRequest
42 голосов
/ 22 декабря 2010

У меня много файлов с расширением .txt.Как удалить расширение .txt для нескольких файлов в Linux?

Я обнаружил, что

rename .old .new *.old

заменяет расширение .old на .new

Также я хочусделать это для файлов в подпапках.

Ответы [ 8 ]

69 голосов
/ 22 декабря 2010

rename немного опасно, так как в соответствии с его страницей руководства :

переименование переименует указанные файлы, заменив первое вхождение...

Он с радостью сделает что-то не так с именами файлов, такими как c.txt.parser.y.

Вот решение с использованием find и bash:

find -type f -name '*.txt' | while read f; do mv "$f" "${f%.txt}"; done

Имейте в виду, что это сломается, если имя файла содержит новую строку (редко, но не невозможно).

Если у вас есть GNU find, это более надежное решение:

find -type f -name '*.txt' -print0 | while read -d $'\0' f; do mv "$f" "${f%.txt}"; done
19 голосов
/ 05 июня 2013

Я использую это:

find ./ -name "*.old" -exec sh -c 'mv $0 `basename "$0" .old`.new' '{}' \;
13 голосов
/ 06 ноября 2013

Версия переименования Perl может удалить расширение следующим образом:

rename 's/\.txt$//' *.txt

Это может быть объединено с find для того, чтобы также выполнять подпапки.

11 голосов
/ 22 декабря 2010

Вы можете явно передать пустую строку в качестве аргумента.

rename .old '' *.old

И с подпапками find . -type d -exec rename .old '' {}/*.old \;. {} является заменой записи, найденной с find, а \; завершает arglist для команды, указанной после -exec.

3 голосов
/ 05 июня 2017

Если это поможет, вот как я это делаю с zsh:

for f in ./**/*.old; do
    mv "${f}" "${f%.old}"
done

Конструкция ${x%pattern} в zsh удаляет кратчайшее вхождение pattern в конце $x.Здесь оно абстрагируется как функция:

function chgext () {
    local srcext=".old"
    local dstext=""
    local dir="."

    [[ "$#" -ge 1 ]] && srcext="$1"
    [[ "$#" -gt 2 ]] && dstext="$2" dir="$3" || dir="${2:-.}"

    local bname=''
    for f in "${dir}"/**/*"${srcext}"; do
        bname="${f%${srcext}}"
        echo "${bname}{${srcext} → ${dstext}}"
        mv "${f}" "${bname}${dstext}"
    done
}

Использование:

chgext
chgext src
chgext src dir
chgext src dst dir

Where `src` is the extension to find (default: ".old")
      `dst` is the extension to replace with (default: "")
      `dir` is the directory to act on (default: ".")
1 голос
/ 02 августа 2016

В Рыбе вы можете сделать

for file in *.old
      touch (basename "$file" .old).new
end
1 голос
/ 22 декабря 2010

Для подпапок:

for i in `find myfolder -type d`; do
  rename .old .new $i/*.old
done
0 голосов
/ 03 марта 2019

выполнить в Bash Linux

for i in *;do mv ${i} ${i/%.pdf/} ;done
...