Namen von inkrementell geordneten Dateibereichen ändern

Namen von inkrementell geordneten Dateibereichen ändern

Angenommen, ich habe einen Dateibereich mit den Namen „bla-10-bla“, „bla-11-bla“ usw. bis „bla-30-bla“.

Ich würde die Namen gerne in „bla-20-bla“, „bla-21-bla“ usw. ändern … bis hin zu „bla-40-bla“.

Gibt es eine Möglichkeit, dies im Terminal zu tun?

Antwort1

Du kannst tun:

#!/bin/bash
files=( blah-??-blah )
for ((i=${#files[@]}-1; i>=0; i--)); do

    first="${files[$i]%%-*}" 
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" 
    last="${files##*-}"

        echo mv "$first-$num-$last" "$first-$((num+10))-$last" 
done

Wenn Sie mit allem zufrieden sind, fügen Sie | basham Ende hinzu, dass der mvVorgang ausgeführt werden soll.

  • Wir haben die relevanten Dateinamen in ein Array gepacktfiles

  • Dann haben wir über die Elemente des Arrays vom Ende iteriert, also vom letzten zum ersten

  • firstwird den ersten Teil des Dateinamens haben, also den Teil vor dem ersten-

  • lastenthält den letzten Teil des Dateinamens, also den Teil nach dem letzten-

  • numwird die Zahl zwischen zwei-

  • mv "$first-$num-$last" "$first-$((num+10))-$last"wird die Umbenennungsoperation entsprechend durchführen

Beispiel:

$ ls -1
blah-10-blah
blah-11-blah
blah-12-blah
blah-13-blah
blah-14-blah
blah-15-blah
blah-16-blah
blah-17-blah
blah-18-blah
blah-19-blah
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-foo-1
blah-foo-2

$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}"; \ 
      echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done

mv blah-30-blah blah-40-blah
mv blah-29-blah blah-39-blah
mv blah-28-blah blah-38-blah
mv blah-27-blah blah-37-blah
mv blah-26-blah blah-36-blah
mv blah-25-blah blah-35-blah
mv blah-24-blah blah-34-blah
mv blah-23-blah blah-33-blah
mv blah-22-blah blah-32-blah
mv blah-21-blah blah-31-blah
mv blah-20-blah blah-30-blah
mv blah-19-blah blah-29-blah
mv blah-18-blah blah-28-blah
mv blah-17-blah blah-27-blah
mv blah-16-blah blah-26-blah
mv blah-15-blah blah-25-blah
mv blah-14-blah blah-24-blah
mv blah-13-blah blah-23-blah
mv blah-12-blah blah-22-blah
mv blah-11-blah blah-21-blah
mv blah-10-blah blah-20-blah

$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}";\ 
      echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done | bash

$ ls -1
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-31-blah
blah-32-blah
blah-33-blah
blah-34-blah
blah-35-blah
blah-36-blah
blah-37-blah
blah-38-blah
blah-39-blah
blah-40-blah
blah-foo-1
blah-foo-2

Antwort2

Es ist wichtig, die Dateien in umgekehrter numerischer Reihenfolge zu verarbeiten, da die Aufgabe sonst fehlschlägt, da bereits Dateien mit dem Zieldateinamen vorhanden sind:

find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
  • find . -maxdepth 1 -type f -name 'blah-??-blah' -print0: druckt eine durch NULL getrennte Liste der Dateien im aktuellen Arbeitsverzeichnis, die dem Globbing-Muster entsprechen blah-??-blah;
  • sort -zr: sortiert die Liste in umgekehrter numerischer Reihenfolge;
  • xargs -0 rename 's/-\K([0-9]{2})/$1+10/e': benennt die Dateien um, indem die ersten Ziffern nach einem Bindestrich durch den entsprechenden um 10 erhöhten Wert ersetzt werden;
% tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah

0 directories, 21 files
% find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
% tree
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah

0 directories, 21 files

Bei Verwendung von Zsh kann die Aufgabe erheblich vereinfacht werden, da Zsh die Erweiterung von Dateinamen in umgekehrter numerischer Reihenfolge ermöglicht:

rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah

0 directories, 21 files
% rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree                                
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah

0 directories, 21 files

Antwort3

Die Grundidee dieses Ansatzes besteht darin, alle Dateien in ein temporäres „Korb“-Verzeichnis zu werfen, sie dann einzeln herauszusuchen, einen neuen Namen zu erstellen und sie mit dem neuen Namen wieder in das ursprüngliche Verzeichnis zu verschieben.

Das folgende Skript verwendet ein einzelnes Argument ( $1 ), nämlich das Verzeichnis, in dem sich die Dateien befinden, die Sie umbenennen möchten.

Demo

xieerqi:$ ls testdir                                                                                         
blah-10-blah  blah-20-blah  blah-30-blah  blah-40-blah

xieerqi:$ cat testdir/*                                                                                      
I am file 10 
I am file 20 
I am file 30 
I am file 40 

xieerqi:$ ./incrementNames.sh testdir                                                                        
blah-10-blah ../blah-20-blah
blah-20-blah ../blah-30-blah
blah-30-blah ../blah-40-blah
blah-40-blah ../blah-50-blah

xieerqi:$ ls testdir
blah-20-blah  blah-30-blah  blah-40-blah  blah-50-blah  TMP/

xieerqi:$ cat testdir/blah                                                                                   
blah-20-blah blah-30-blah blah-40-blah blah-50-blah 
xieerqi:$ cat testdir/blah-20-blah                                                                           
I am file 10 

xieerqi:$ cat testdir/blah-30-blah                                                                           
I am file 20 

Skript

#!/bin/bash

if [ "$#" -ne 1 ]; then
    echo "Usage: incrementNames.sh /path/to/dir" && exit
fi

# navigate to target directory
# create temporary directory
cd "$1"
mkdir TMP
# move everything to TMP directory
find . -maxdepth 1 -type f -iname "*-*" -exec mv -t TMP {} \+
# drop down to TMP directory pick filesback into the directory , and rename them as we go
cd TMP
find .  -maxdepth 1 -type f -iname "*-*" -printf "%f\n"  | sort  | while IFS= read FILENAME
do
        NEW="$( awk -F '-'  '{print $1FS$2+10FS$3 }' <<< "$FILENAME")"
        echo "$FILENAME" "../$NEW" 
        mv "$FILENAME" ../"$NEW"
done

Einschränkung

Dieses Skript ist speziell für Dateien gedacht text-number-text, die dem Muster oder zumindest text-numberdem Muster folgen. Bei anderen funktioniert es nicht

verwandte Informationen