Bagaimana cara mengganti nama dengan prefiks / sufiks?

95

Bagaimana saya melakukannya mv original.filename new.original.filenametanpa mengetik ulang nama file asli?

Saya membayangkan bisa melakukan sesuatu seperti mv -p=new. original.filenameatau mungkin mv original.filename new.~atau apa pun - tetapi saya tidak dapat melihat hal seperti ini setelah melihat man mv/ info mvpages.

Tentu saja, saya dapat menulis skrip shell untuk melakukan ini, tetapi bukankah sudah ada perintah / bendera untuk itu?

Peter Boughton
sumber

Jawaban:

122

Di Bash dan zsh Anda dapat melakukan ini dengan Brace Expansion . Ini hanya memperluas daftar item di kawat gigi. Sebagai contoh:

# echo {vanilla,chocolate,strawberry}-ice-cream
vanilla-ice-cream chocolate-ice-cream strawberry-ice-cream

Jadi, Anda dapat melakukan penggantian nama sebagai berikut:

mv {,new.}original.filename

karena ini berkembang menjadi:

mv original.filename new.original.filename
Dave Webb
sumber
Terima kasih, ini tampaknya solusi terbaik - juga berfungsi dengan ksh.
Peter Boughton
29
Apa yang tidak dilakukan ini adalah bekerja dengan kartu liar. Yaitu, dalam direktori yang berisi nama file a, b, c, menggunakan "echo {, new.} *" Menghasilkan daftar "abc baru. *" (Karena pembuatan nama file melalui perluasan tanda kurung terjadi sebelum memperluas karakter wild card - setidaknya dengan kesimpulan).
Jonathan Leffler
Sejak berbulan-bulan saya mencari solusi seperti itu hanya menggunakan fungsi shell dasar ... Saya tidak akan pernah menemukan sesuatu yang sederhana, terima kasih banyak!
flonk
Terima kasih atas referensi ke Brace Expansion :-) persis seperti yang saya cari!
Pim Hazebroek
1
Saya suka contohnya. Saya sedang ingin pergi ke Baskin Robbins saat istirahat makan siang.
Sridhar Sarnobat
157

Anda bisa menggunakan rename(1)perintah:

rename 's/(.*)$/new.$1/' original.filename

Sunting: Jika renametidak tersedia dan Anda harus mengganti nama lebih dari satu file, skrip shell benar-benar bisa singkat dan sederhana untuk ini. Misalnya, untuk mengganti nama semua *.jpgmenjadi prefix_*.jpgdi direktori saat ini:

for filename in *.jpg; do mv "$filename" "prefix_$filename"; done;
Simon Lehmann
sumber
Grafit yang diinstal akhir pekan ini, dan mereka memiliki langkah yang pada dasarnya ("salin semua file * .example ke dalam folder conf, hapus sufiks contoh"). Benar-benar malas di pihak mereka, tetapi rename 's/(.*).example/$1/' *.examplemenyelamatkan saya dari kebosanan.
Conrad.Dean
2
Ini adalah jawaban terbaik sejauh ini.
lifeisfoo
Saya tidak berpikir Anda membutuhkan yang pertama $dalam skenario ini. Jadi hanya's/(.*)/new.$1/'
beruntung
1
renameperintah tidak berfungsi pada mesin RHEL 6 saya. Apakah ada versi berbeda dari perintah ini? Itu for ... doneberhasil untuk saya.
robsch
25

Anda dapat mencapai beberapa penggantian nama file yang kompatibel dengan unix (menggunakan wildcard) dengan membuat for loop:

for file in *; do
  mv $file new.${file%%}
done
A Muguro
sumber
7
Apa perbedaan antara ini dan apa yang sudah dijawab oleh Simon Lehmann ?
Peter Boughton
4
Ini bekerja dengan baik. Apa yang kamu ${file%%}lakukan? Tampak mirip dengan hanya $ {file}
Sidmitra
Saya ingin tahu tentang $ {file %%} juga
Lucas Bustamante
10

Saya telah melihat orang-orang menyebutkan sebuah renameperintah, tetapi tidak secara rutin tersedia di sistem Unix (sebagai lawan dari sistem Linux, katakanlah, atau Cygwin - di keduanya, mengganti nama adalah yang dapat dieksekusi daripada skrip). Versi tersebut renamememiliki fungsi yang cukup terbatas:

rename from to file ...

Ini menggantikan dari bagian dari nama file dengan to , dan contoh yang diberikan di halaman manual adalah:

rename foo foo0 foo? foo??

Ini mengganti nama foo1 menjadi foo01, dan foo10 menjadi foo010, dll.

Saya menggunakan skrip Perl yang disebut rename, yang awalnya saya gali dari buku Camel edisi pertama, sekitar tahun 1992, dan kemudian diperpanjang, untuk mengganti nama file.

#!/bin/perl -w
#
# @(#)$Id: rename.pl,v 1.7 2008/02/16 07:53:08 jleffler Exp $
#
# Rename files using a Perl substitute or transliterate command

use strict;
use Getopt::Std;

my(%opts);
my($usage) = "Usage: $0 [-fnxV] perlexpr [filenames]\n";
my($force) = 0;
my($noexc) = 0;
my($trace) = 0;

die $usage unless getopts('fnxV', \%opts);

if ($opts{V})
{
    printf "%s\n", q'RENAME Version $Revision: 1.7 $ ($Date: 2008/02/16 07:53:08 $)';
    exit 0;
}
$force = 1 if ($opts{f});
$noexc = 1 if ($opts{n});
$trace = 1 if ($opts{x});

my($op) = shift;
die $usage unless defined $op;

if (!@ARGV) {
    @ARGV = <STDIN>;
    chop(@ARGV);
}

for (@ARGV)
{
    if (-e $_ || -l $_)
    {
        my($was) = $_;
        eval $op;
        die $@ if $@;
        next if ($was eq $_);
        if ($force == 0 && -f $_)
        {
            print STDERR "rename failed: $was - $_ exists\n";
        }
        else
        {
            print "+ $was --> $_\n" if $trace;
            print STDERR "rename failed: $was - $!\n"
                unless ($noexc || rename($was, $_));
        }
    }
    else
    {
        print STDERR "$_ - $!\n";
    }
}

Ini memungkinkan Anda untuk menulis pengganti Perl atau perintah transliterasi untuk memetakan nama file. Dalam contoh khusus yang diminta, Anda akan menggunakan:

rename 's/^/new./' original.filename
Jonathan Leffler
sumber
Terima kasih, jika saya bisa menerima jawaban kedua, inilah jawabannya. Saya menginginkan perintah standar sebagai sesuatu yang hanya akan berfungsi pada apa pun yang mungkin saya gunakan, tetapi saya dapat meletakkan skrip ini pada mesin yang sering saya gunakan dan itu masih akan membantu.
Peter Boughton
James Wong mencatat bahwa untuk Arch Linux, Anda bisa men-download dan menginstal script ini melalui pacmanmenggunakan: pacman -Sy perl-rename. Kemudian tambahkan alias di bashrc Anda:alias rename='perl-rename'
Jonathan Leffler
bagaimana jika "dari" atau "ke" adalah string kosong, yaitu Anda ingin menambahkan sesuatu ke setiap nama file atau menghapus sesuatu sepenuhnya
Troyseph
1
@Troyseph - untuk menambahkan '.htmlnama file, gunakan 's/$/.html/'- untuk menghapus tmpdari mana saja di nama file, gunakan 's/tmp//g'(temukan tmpdan ganti dengan tidak ada di mana-mana).
Jonathan Leffler
4

Cara termudah untuk mengganti nama file dalam direktori secara massal adalah:

ls | xargs -I fileName mv fileName fileName.suffix
Brajan Elektro
sumber
2

Jika terbuka untuk modifikasi, Anda dapat menggunakan sufiks sebagai ganti awalan. Kemudian Anda bisa menggunakan penyelesaian-tab untuk mendapatkan nama file asli dan menambahkan sufiks.

Jika tidak, ini bukan sesuatu yang didukung oleh perintah mv. Skrip shell sederhana bisa mengatasinya.

workmad3
sumber
Seringkali saya menginginkan keduanya, tetapi terutama awalan - seperti yang Anda katakan, penyelesaian tab dapat menangani sufiks.
Peter Boughton
1

Dalam kasus saya, saya memiliki sekelompok file yang perlu diganti namanya sebelum saya dapat bekerja dengannya. Setiap file memiliki perannya sendiri dalam grup dan memiliki polanya sendiri.

Akibatnya saya memiliki daftar perintah ganti nama seperti ini:

f=`ls *canctn[0-9]*`   ;  mv $f  CNLC.$f
f=`ls *acustb[0-9]*`   ;  mv $f  CATB.$f
f=`ls *accusgtb[0-9]*` ;  mv $f  CATB.$f
f=`ls *acus[0-9]*`     ;  mv $f  CAUS.$f

Coba ini juga:

f=MyFileName; mv $f {pref1,pref2}$f{suf1,suf2}

Ini akan menghasilkan semua kombinasi dengan prefiks dan sufiks:

pref1.MyFileName.suf1
...
pref2.MyFileName.suf2

Cara lain untuk mengatasi masalah yang sama adalah dengan membuat larik pemetaan dan menambahkan awalan koresponden untuk setiap jenis file seperti yang ditunjukkan di bawah ini:

#!/bin/bash
unset masks
typeset -A masks
masks[ip[0-9]]=ip
masks[iaf_usg[0-9]]=ip_usg
masks[ipusg[0-9]]=ip_usg
...
for fileMask in ${!masks[*]}; 
do  
registryEntry="${masks[$fileMask]}";
fileName=*${fileMask}*
[ -e ${fileName} ] &&  mv ${fileName} ${registryEntry}.${fileName}  
done
aprodan
sumber
1

Ganti nama file secara massal skrip bash

#!/bin/bash
# USAGE: cd FILESDIRECTORY; RENAMERFILEPATH/MultipleFileRenamer.sh FILENAMEPREFIX INITNUMBER
# USAGE EXAMPLE: cd PHOTOS; /home/Desktop/MultipleFileRenamer.sh 2016_
# VERSION: 2016.03.05.
# COPYRIGHT: Harkály Gergő | mangoRDI (https://wwww.mangordi.com/) 

# check isset INITNUMBER argument, if not, set 1 | INITNUMBER is the first number after renaming
if [ -z "$2" ]
    then i=1;
else
    i=$2;
fi

# counts the files to set leading zeros before number | max 1000 files
count=$(ls -l * | wc -l)
if [ $count -lt 10 ]
    then zeros=1;
else
    if [ $count -lt 100 ]
        then zeros=2;
    else
        zeros=3
    fi
fi

# rename script
for file in *
do
    mv $file $1_$(printf %0"$zeros"d.%s ${i%.*} ${file##*.})
    let i="$i+1"
done
Harkály Gergő
sumber
1

Saya tahu ada jawaban bagus di sini tetapi saya tidak menemukan referensi untuk menangani ekstensi nama file saat menambahkan sufiks.

Saya perlu menambahkan akhiran '_en' ke semua wavfile di folder sebelum ekstensi file.

Keajaiban ada di sini: %.*

for filename in *.wav; do mv $filename ${filename%.*}_en.wav; done;

Jika Anda perlu menangani ekstensi file yang berbeda, periksa jawaban ini . Sedikit kurang intuitif.

ya
sumber