добавление текста к имени файла перед расширением

25

Я хотел бы добавить текст в конец имени файла, но перед расширением. Сейчас я пытаюсь,

for f in *.shp; do echo $f_poly; done

выход есть,

Quercus_acutifolia.shp_poly
Quercus_agrifolia.shp_poly
Quercus_corrugata.shp_poly
Quercus_cortesii.shp_poly
Quercus_costaricensis.shp_poly
Quercus_havardii.shp_poly
Quercus_hemisphaerica.shp_poly
Quercus_kelloggii.shp_poly
Quercus_knoblochii.shp_poly
Quercus_laceyi.shp_poly

Я хочу, чтобы это было,

Quercus_acutifolia_poly.shp
Quercus_agrifolia_poly.shp
Quercus_corrugata_poly.shp
Quercus_cortesii_poly.shp
Quercus_costaricensis_poly.shp
Quercus_havardii_poly.shp
Quercus_hemisphaerica_poly.shp
Quercus_kelloggii_poly.shp
Quercus_knoblochii_poly.shp
Quercus_laceyi_poly.shp
Sam007
источник

Ответы:

27

Используя стандартное расширение параметра POSIX :

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done
jw013
источник
Круто, это именно то, что мне было нужно.
Sam007
1
Может быть лучше с объяснением, как это работает. С другой стороны, ответ Дуга довольно прост.
Сардж Борщ
@SargeBorsch Что тебе нужно объяснить? Мой ответ, фрагмент в вопросе и ответ Дуга отличаются только на несколько символов, и ответ Дуга объясняет даже меньше, чем мой, поэтому я не знаю, чего вы хотите. Если вы просто сравните разницу в двух выходах в вопросе, будет легко понять, что они делают. Я могу объяснить, почему мой ответ предпочтительнее ответа Дага. 1. Я использую printfформатную строку вместо менее переносимой echo. 2. Я использую расширение параметров, которое более эффективно, чем вызов внешнего двоичного кода ( basename) для такой простой задачи.
jw013
Тогда команда для переименования файлов будет такой:for f in *.shp; do mv $f ${f%.shp}_poly.shp; done
Patch92
6

Иногда установлен инструмент под названием «переименовать».

rename 's/\.shp$/_poly.shp/' *shp

Он может быть не портативным, но простым в использовании.

Чед Кларк
источник
1
Это единственный, который работал на меня, отличный ответ!
wanderer0810
4

Использовать этот:

for file in *.shp; do echo $(basename $file .shp)_poly.shp; done
doneal24
источник
3
Использование basenameмедленнее и менее эффективно, чем позволить оболочке выполнять работу самостоятельно. Это может быть заметно для очень большого количества файлов.
jw013
Кроме того, отсутствуют кавычки и --s, и он не работает для имен файлов, которые имеют символы новой строки перед .shp.
Стефан Шазелас
Спасибо за ответ, с которым я действительно могу работать в своих целях. Это помощь Bash, а не код гольф. (читаю над этим ... Я понимаю, что это могло звучать так, будто я был саркастичен. Более захватывающий, чем ваш, ответ на другие ответы здесь. Еще раз спасибо)
Тим
3

Это работало лучше для меня:

for f in *; do NEW=${f%.webm}_2016.webm; mv ${f} "${NEW}"; done

Винни Джеймс
источник
Ну, это очень похоже на принятый ответ, за исключением того, что вы, вероятно, хотите for f in *.webm, вы забыли процитировать ${f}и вы пропустили --.
Стефан Шазелас
1
Принятый ответ не работает на OSX, он только печатает новые имена файлов, он фактически не переименовывает файлы
Винни Джеймс
1
Конечно, он показывает вам, как использовать расширения оболочки для получения нового имени файла, в ответ на вопрос, который также выводит имя файла (с echo), но не требуемое.
Стефан Шазелас
1

Если они находятся в разных местах, выполните:

for i in ` find /root/test/ -name "*.shp" ` ;
do
  mv $i ` echo $i | sed 's/.shp$/_poly.shp/g' ` ;
done
Шенки Рави
источник
1

Поскольку вопрос в том, bashчто нет необходимости во внешних утилитах, так как вы можете использовать регулярные выражения bash :

for i in *.shp
do
    mv -v "${i}" "${i%.*}_MYSUFFIX.${i##*.}"
done
ccpizza
источник