Wie benenne ich mit Präfix / Suffix um?


95

Wie gehe ich vor, mv original.filename new.original.filenameohne den ursprünglichen Dateinamen erneut einzugeben?

Ich würde mir vorstellen, so etwas mv -p=new. original.filenameoder vielleicht mv original.filename new.~oder was auch immer tun zu können - aber ich kann so etwas nicht sehen, nachdem ich mir man mv/ info mvpages angesehen habe.

Natürlich könnte ich dazu ein Shell-Skript schreiben, aber gibt es dafür keinen vorhandenen Befehl / Flag?

Antworten:


122

In Bash und zsh können Sie dies mit Brace Expansion tun . Dadurch wird einfach eine Liste von Elementen in geschweiften Klammern erweitert. Beispielsweise:

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

Sie können also wie folgt umbenennen:

mv {,new.}original.filename

da dies erweitert zu:

mv original.filename new.original.filename

Danke, das scheint die beste Lösung zu sein - funktioniert auch mit ksh.
Peter Boughton

29
Dies funktioniert nicht mit Platzhaltern. Das heißt, in einem Verzeichnis mit den Dateinamen a, b, c ergibt die Verwendung von "echo {, new.} *" Die Liste "abc new. *" (Da die Generierung von Dateinamen über die Erweiterung von Klammern erfolgt, bevor Platzhalterzeichen erweitert werden - zumindest durch Folgerung).
Jonathan Leffler

Seit Monaten suche ich nach einer solchen Lösung, die nur grundlegende Shell-Funktionen verwendet ... Ich hätte mir nie etwas so Einfaches ausgedacht, vielen Dank!
Flonk

Danke für den Hinweis auf Brace Expansion :-) genau das, wonach ich gesucht habe!
Pim Hazebroek

1
Ich liebe das Beispiel. Ich habe das Gefühl, jetzt während meiner Mittagspause zu Baskin Robbins zu gehen.
Sridhar Sarnobat

156

Sie können den folgenden rename(1)Befehl verwenden:

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

Bearbeiten: Wenn renamees nicht verfügbar ist und Sie mehr als eine Datei umbenennen müssen, kann Shell-Scripting sehr kurz und einfach sein. Zum Beispiel können alle umbenennen , *.jpgum prefix_*.jpgim aktuellen Verzeichnis:

for filename in *.jpg; do mv "$filename" "prefix_$filename"; done;

Dieses Wochenende wurde Graphit installiert, und sie haben einen Schritt, der im Wesentlichen so ist ("Kopieren Sie alle * .example-Dateien in den Ordner conf und entfernen Sie das Beispielsuffix"). Wirklich faul von ihrer Seite, aber rename 's/(.*).example/$1/' *.examplerettete mich vor der Langeweile.
Conrad.Dean

2
Dies ist die bisher beste Antwort.
Lifeisfoo

Ich glaube nicht, dass Sie den ersten $in diesem Szenario brauchen . Also einfach's/(.*)/new.$1/'
wisbucky

1
renameDer Befehl funktioniert auf meinem RHEL 6-Computer nicht. Gibt es verschiedene Versionen dieses Befehls? Das for ... donehat bei mir funktioniert.
Robsch


10

Ich habe Leute gesehen, die einen renameBefehl erwähnt haben, aber er ist auf Unix-Systemen nicht routinemäßig verfügbar (im Gegensatz zu Linux-Systemen oder Cygwin - auf beiden ist das Umbenennen eher eine ausführbare Datei als ein Skript). Diese Version von renamehat eine ziemlich eingeschränkte Funktionalität:

rename from to file ...

Es ersetzt den from- Teil der Dateinamen durch den to , und das in der Manpage angegebene Beispiel lautet:

rename foo foo0 foo? foo??

Dadurch wird foo1 in foo01 und foo10 in foo010 usw. umbenannt.

Ich verwende ein Perl-Skript namens rename, das ich ursprünglich aus der ersten Ausgabe des Camel-Buches um 1992 ausgegraben und dann erweitert habe, um Dateien umzubenennen.

#!/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";
    }
}

Auf diese Weise können Sie einen beliebigen Perl-Ersatz- oder Transliterationsbefehl schreiben, um Dateinamen zuzuordnen. In dem angeforderten Beispiel würden Sie Folgendes verwenden:

rename 's/^/new./' original.filename

Danke, wenn ich eine zweite Antwort akzeptieren könnte, wäre es das. Ich wollte einen Standardbefehl als etwas, das nur für alles funktioniert, was ich verwenden könnte, aber ich kann dieses Skript auf die Maschinen setzen, die ich häufig benutze, und es wird immer noch hilfreich sein.
Peter Boughton

James Wong merkt an, dass Sie dieses Skript für Arch Linux einfach herunterladen und installieren können, pacmanindem Sie Folgendes verwenden : pacman -Sy perl-rename. Fügen Sie dann einen Alias ​​in Ihrem Bashrc hinzu:alias rename='perl-rename'
Jonathan Leffler

Was ist, wenn "von" oder "bis" leere Zeichenfolgen sind, dh Sie möchten jedem Dateinamen etwas anhängen oder etwas vollständig entfernen
Troyseph

1
@Troyseph - zum Anhängen '.htmlan die Dateinamen verwenden, 's/$/.html/'- tmpvon überall in den Dateinamen entfernen , verwenden 's/tmp//g'( tmpüberall suchen und durch nichts ersetzen).
Jonathan Leffler

4

Der einfachste Weg, Dateien im Verzeichnis in großen Mengen umzubenennen, ist:

ls | xargs -I fileName mv fileName fileName.suffix

2

Wenn eine Änderung möglich ist, können Sie anstelle eines Präfixes ein Suffix verwenden. Dann können Sie die Tab-Vervollständigung verwenden, um den ursprünglichen Dateinamen abzurufen und das Suffix hinzuzufügen.

Andernfalls wird dies vom Befehl mv nicht unterstützt. Ein einfaches Shell-Skript könnte dies jedoch bewältigen.


Oft möchte ich beides, aber in erster Linie das Präfix - wie Sie sagen, kann die Tab-Vervollständigung Suffixe verarbeiten.
Peter Boughton

1

In meinem Fall habe ich eine Gruppe von Dateien, die umbenannt werden müssen, bevor ich mit ihnen arbeiten kann. Jede Datei hat ihre eigene Rolle in der Gruppe und ein eigenes Muster.

Als Ergebnis habe ich eine Liste von Umbenennungsbefehlen wie folgt:

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

Versuchen Sie dies auch:

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

Dies erzeugt alle Kombinationen mit Präfixen und Suffixen:

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

Eine andere Möglichkeit, dasselbe Problem zu lösen, besteht darin, ein Zuordnungsarray zu erstellen und für jeden Dateityp ein entsprechendes Präfix hinzuzufügen, wie unten gezeigt:

#!/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

1

Bulk-Skript zum Umbenennen von Dateien

#!/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

0

Ich weiß, dass es hier gute Antworten gibt, aber ich habe beim Hinzufügen von Suffix keine Referenz gefunden, um Dateinamenerweiterungen zu behandeln.

Ich musste allen wavDateien in einem Ordner vor der Dateierweiterung das Suffix '_en' hinzufügen .

Die Magie ist hier: %.*

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

Wenn Sie verschiedene Dateierweiterungen verarbeiten müssen, überprüfen Sie diese Antwort. Ein bisschen weniger intuitiv.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.