2016-11-17 3 views
1

Ich habe eine zufällige Anzahl von Dateien mit Namen wie:Generierung systematische inkrementelle nummerierte Dateinamen in Bash

id_1000.txt 
id_2000.txt 
id_3000.txt 
id_4000.txt 

Beachten Sie, dass die Anzahl der .txt Dateien in verschiedenen Verzeichnissen variiert. Zum Beispiel kann ein Verzeichnis nur eine id_1000.txt (mindestens) enthalten oder eine beliebige Anzahl von Dateien mit einer höheren Anzahl von Ziffern enthalten.

Um die Zufallszahl von Dateinamen in systematischer inkrementeller Zahl zu konvertieren, habe ich in einem Batch-Skript folgende Skript:

setlocal enabledelayedexpansion 
set /a count=1 
for /f "tokens=*" %%a in ('dir /b /od *.txt') do (
echo ren "%%a" "id_!count!.txt" 
set /a count+=1 
) 

Der Ausgang für die obige Eingabe wäre:

ren "id_1000.txt" "id_1.txt" 
ren "id_2000.txt" "id_2.txt" 
ren "id_3000.txt" "id_3.txt" 
ren "id_4000.txt" "id_4.txt" 

Er erkennt zuerst die Anzahl der id_*.txt Dateien, die sich im aktuellen Verzeichnis befinden, und wechselt dann zu der höheren Nummer mit der normalen Zählreihenfolge: 1, 2, 3, 4 usw. und echo eine Zeile.

Obwohl ich versuchte, nach alternativen Befehlen für Ubuntu zu suchen, konnte ich kein befriedigendes Ergebnis finden.

Ich bin sehr neu in der Linux-Shell, jede Hilfe in dieser Angelegenheit wird geschätzt.

Dank

+0

Der von Ihnen bereitgestellte Beispielcode ist jedoch Batch-Programmierung. Sie möchten diesen Anwendungsfall auf einer Linux/Unix-basierten Maschine oder auf einer Windows-Maschine ausführen? – Inian

+0

Ich möchte es in bash konvertieren. Ich arbeitete vorher in Windows-Maschine, aber curently Migration zu Linux –

Antwort

2
shopt -s globstar 
n=0 
for a in **/*.txt; do 
     ((n++)) 
     mv "$a" id_$n.txt 
done  
+0

funktioniert es in meiner Verzeichnisstruktur, noch eine Frage, wie kann ich die generierten Zeilen direkt in einer separaten Datei drucken? Ich versuche >> file.txt, aber Bash gibt die Erlaubnis verweigert –

0

Wenn die Dateien in dem Format, das Sie in Ihrer Frage liefern, sollte diese Work-

#Get the number of .txt. files to be renamed  
    num=$(ls id_*.txt | wc -l) 
#Rename them 
    for i in $(seq 1 "$num") 
    do 
     mv id_"$num"000.txt id_"$num".txt 
    done 

einen Testlauf in einem Testordner, bevor Sie es auf der Flucht tatsächliche Dateien.

+0

, aber die Zahlen können zufällig sein –

+0

@ J.Carter Sie sollten Ihre Frage widerspiegeln, dass Zufälligkeit. Wie auch immer, ich bin froh, dass du eine Antwort bekommen hast, die für dich funktioniert. – VM17

1

Angenommen, Sie das folgende Dateisystemlayout haben:

Dir 
├── A 
│   ├── id_1000.txt 
│   ├── id_2000.txt 
│   ├── id_3000.txt 
│   └── id_4000.txt 
├── id_5000.txt 
├── id_6000.txt 
├── id_7000.txt 
└── id_8000.txt 

Dann können Sie ein Skript ähnlich den folgenden verwenden:

let i=1 
find "./Dir" -type f -regex '.*id_[0-9]+\.txt' | while read file 
do 
    mv "$file" "${file/%id_*.txt/id_$i}.txt" 
    ((++i)) 
done 

Das Skript wird die Dateien umbenennen, wie folgt:

Dir 
├── A 
│   ├── id_1.txt 
│   ├── id_2.txt 
│   ├── id_3.txt 
│   └── id_4.txt 
├── id_5.txt 
├── id_6.txt 
├── id_7.txt 
└── id_8.txt 

Die let builtin wird für arithmetische Ausdrücke verwendet. Im obigen Skript initialisierten wir i Variable mit Wert 1.

Die find Befehl sucht nach Dateien (-type f) im Verzeichnis ./Dir die Pfade regular expression'.*id_[0-9]+\.txt' und Ausgänge Zeilen der Datei übereinstimmen. Der Ausgang ist mit der while Schleife über pipe verbunden. Dies bedeutet, dass die Schleife mit der anderen Seite des Rohrs verbunden ist und Pfade zeilenweise liest.

Die ${file/%id_*.txt/id_$i} Ausdruck substitutesid_$i für id_*.txt. Die nächste Zeile (((++i))) ist ein arithmetischer Ausdruck, der die Variable i inkrementiert.

Hinweis: Wenn Sie den Effekt des Skripts auf eine bestimmte Verzeichnisebene beschränken möchten, verwenden Sie die Option find-maxdepth.

Verwandte Themen