Переименуйте все расширение файла в каталоге

Я плохо знаком со сценариями, и у меня есть каталог со всеми файлами, названными num.pdb.ostat. Я хотел бы переименовать весь num.ostat (который удаляет .pdb всего). Для единственного файла это работает:

mv 2.pdb.ostat 2.ostat

но когда я пытаюсь сделать это для всех файлов в папке с этим сценарием

for num in ./*; do mv ${num}.pdb.ostat ${num}.ostat; done

ничего не происходит

Кто-либо может сказать мне, где я пошел не так, как надо?

4
задан 9 March 2015 в 02:20

4 ответа

${num} берет полное имя файла. Вам нужно получить имя файла без расширения и добавить новое расширение. Вы можете сделать форматирование строки. Используйте следующую команду:

for num in ./*; do mv ${num} ${num%.*.*}.ostat ; done

% удаляет самое короткое совпадение $ substring из задней части $ string.

6
ответ дан 23 November 2019 в 11:40

Для устранения неполадок в вашем скрипте попробуйте заменить mv на echo. Вы увидите, что ваша переменная ${num} содержит полное полное имя файла , например, 2.pdb.ostat. Следовательно, ваш скрипт, по сути, пытается запустить

mv ./2.pdb.ostat.pdb.ostat ./2.pdb.ostat.ostat

Вместо этого вы должны сначала урезать имя файла до простого числа. например,

for filename in ./*; do num="$(echo "${filename}" | grep -o '^./[0-9]*')"; echo "${num}.pdb.ostat" "${num}.ostat"; done

Как только вы подтвердите, что синтаксис в порядке, вы можете изменить echo на mv и фактически переместить файлы. т.е.

for filename in ./*; do num="$(echo "${filename}" | grep -o '^./[0-9]*')"; mv "${num}.pdb.ostat" "${num}.ostat"; done

Тем не менее, самый простой способ - использовать (perl) переименование.

rename 's/pdb.//' *.pdb.ostat –

См. man rename для получения дополнительной информации.

5
ответ дан 23 November 2019 в 11:40

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

#!/bin/bash

#renext.sh
# a bash script for changing the extension of files.
echo "what extension would you like to change in this directory?"
read oldext
echo "To what?"
read newext
for f in *.* 
do
    name=$(echo "$f" | sed 's/\.[^\.]*$//')
    ext=$(echo "$f" | sed 's/^.*\.//')
    target="$name"."$newext"
    echo "source file" "$f" is made up of the base "$name" and ends with "$ext"
    if [ -e "$target" ];
    then 
        echo "$target" exists. skipping renameing.
    else
        mv "$f" "$target"
        echo changed "$f" to "$target"
    fi  

 done

Этот сценарий не повреждается на именах файлов с пробелами и позволяет Вам выбирать входные и выходные расширения.

Это обеспечивает примеры для цикла, читая вход в переменные, с помощью sed для выбора строки независимо в последнем . в строке (имя файла), как пробелы могут быть обработаны правильно путем заключения в кавычки переменных, проверки на существование конечного файла и управление потоком на основе результата теста. Это действительно массово рассылает терминал с ненужным выводом, который может быть устранен простыми строками удаления 14 и 20, которые являются действительно только там для служения в качестве объяснения.

2
ответ дан 23 November 2019 в 11:40

Здесь сценарий, основывающийся на предшествующем ответе. Найдите все файлы в каталоге с именем, содержащим' , Igua' затем переименовывает все файлы включая правильное расширение

#!/bin/bash
for file in *Igua*
do
  let "i++"
  fileext=${file##*.}
  mv "$file" "Iguazu_$i.$fileext"
done
0
ответ дан 23 November 2019 в 11:40

Другие вопросы по тегам:

Похожие вопросы: