DaWi
Anmeldungsdatum: 19. Februar 2008
Beiträge: 132
|
Hallo Gemeinde, Ich habe mal eine Frage: wenn ich 2 Files habe: file-1.txt file-10.txt sind die ,wenn ich ls | sort (bzw. find, locate, was auch immer) mache, ja in der "falschen" Reihenfolge, da 10>1. (Also die sind natürlich in der richtigen Reihenfolge, rein lexikalisch....) Eine Lösung wäre jetzt ja die files umzubennen, also file-001.txt file-010.txt was das Probleme lösen würde. Leider weiß ich nicht wie ich sowas anstellen kann. Ich habe schon rumgesucht, finde aber leider nix. EDIT: bzw. verstehe es nicht Hat jemand eine Idee wie ich das machen könnte? Oder einen besseren Lösungsvorschlag? Grüße DaWi
|
deifl
Anmeldungsdatum: 18. August 2006
Beiträge: 132
Wohnort: Esslingen
|
Wenn die Dateinamen alle mit den gleichen Zeichen vor der Zahl beginnen, also file-1.ext, file-23.ext, file-42.ext, file-20ext, file -100.ext, usw., dann koenntest du mit der zsh folgendes versuchen:
autoload zmv
zmv 'file-(*).ext' 'file-${(l:4::0:)1}.ext' Weitere super Beispiele finden sich bei den zsh-lovers: http://grml.org/zsh/zsh-lovers.html
|
Lutki
Anmeldungsdatum: 17. Juni 2006
Beiträge: 372
|
Na ja, mal eine kleine Anregung - das Skript erst ausführen, wenn du es verstanden hast. #!/bin/bash
dir=`pwd`
i=0
for f in `find $dir -name "*.txt" 2>/dev/null`; do
(( i++ ));
newfile="new-file-`printf %05.f $i`.txt"
if [ ! -f "$dir/$newfile" ]; then
mv "$f" "$dir/$newfile"
fi
done MFG
|
DaWi
(Themenstarter)
Anmeldungsdatum: 19. Februar 2008
Beiträge: 132
|
(( i++ ));
newfile="new-file-`printf %05.f $i`.txt" Mmmmhh, entweder ich versthe das nicht, oder das haut nicht hin. ein beispiel. file-10.txt. file-1.txt (falsche Reihenfolge!, so kommen die ja auch) Also deine Schleife macht dann das. beim ersten i=0. Er printet also 00000 → newfile-00000.txt beim zweiten i=1 Er printet also 00001 → newfile-000001.txt Also: file-10.txt → newfile-00000.txt file-1.txt → newfile-000001.txt Das ist doch wieder in der falschen Reihenfolge, oder nicht? Grüße DaWi ps: Aber printf %0.5.f $i is was ich suche. Ich müsste nun noch diese Zahl aus den files kriegen. was so geht. (habs hinbekommen) bla='file-14.txt' bla2=${bla%.* } bla3=${bla2:5} printf %05.f $bla3 danke für den hinweis mit dem printf
|
DaWi
(Themenstarter)
Anmeldungsdatum: 19. Februar 2008
Beiträge: 132
|
habe es jetzt noch ein wenig hübsch gemacht. 4 Parameter. 1.) Die Weite. also bei file-4235 siond 5, f i l e und -. 2.) Das format 3.) den ausgabe namen, also newfile oder so etwas (wonach dann die neuen nummer kommen) 4.) den eingabe namen (Teilstring), in meinem beispiel file Ich bedanke mich bei allen. Wieder was dazu gelernt Grüße DaWi #!/bin/bash
dir=`pwd`
if [ $# -lt "4" ]
then
echo "Zu wenig infos"
echo "name_skript <Weite> <Format> <Ausgabename> <eingabe_teilstring>"
exit 1
fi
for f in $(find $4* 2>/dev/null)
do
buf1=${f%.*}
buf2=${buf1:$1}
newfile="$3`printf %05.f $buf2`.$2"
if [ ! -f "$dir/$2" ]; then
cp "$f" "$dir/$newfile"
fi
done
|
Lux
Anmeldungsdatum: 10. November 2005
Beiträge: 5152
Wohnort: Grüt (Gossau ZH), Schweiz
|
Hi, vorher Backup machen und versuche dann einmal rename 's/file-(\d{1})\.txt/file-0$1.txt/' * . Damit ersetzt Du in Deinen Dateien alles, wo genau eine Ziffer vorkommt durch 0 und die Ziffer. Wenn Du in die geschweiften Klammern eine 2 schreibst, ersetzt Du alle zweiziffrigen Zahlen durch 0 und die Zahl. Dirk
|
Lutki
Anmeldungsdatum: 17. Juni 2006
Beiträge: 372
|
DaWi hat geschrieben:
Also deine Schleife macht dann das. beim ersten i=0. Er printet also 00000 → newfile-00000.txt beim zweiten i=1 Er printet also 00001 → newfile-000001.txt Also: file-10.txt → newfile-00000.txt file-1.txt → newfile-000001.txt Das ist doch wieder in der falschen Reihenfolge, oder nicht?
Beim ersten $i ist es schon 1; also newfile-00001.txt Der Witz war: es werden alle txt-Dateien geändert, falls es noch keine newfile-XXXXX.txt gibt. ☺ Bei find fehlt bei Dir aber noch das $dir?! MFG
|
DaWi
(Themenstarter)
Anmeldungsdatum: 19. Februar 2008
Beiträge: 132
|
rename 's/file-(\d{1})\.txt/file-0$1.txt/' * Klasse, das klappt auch, da alle einerstellen bearbeitet werden genügt mir dieses Lösung auch. Lutki hat geschrieben: Beim ersten $i ist es schon 1; also newfile-00001.txt Der Witz war: es werden alle txt-Dateien geändert, falls es noch keine newfile-XXXXX.txt gibt. ☺ Bei find fehlt bei Dir aber noch das $dir?!
Also klar, man fängt mit 1 an, ändert aber nichts an der Reihenfolge. Aber du hattes also so eine ähnliche Idee wie Lux. Wenn man dann nämlich printf %02.f $i nimmt, werden nur die einerstellen geändert. So gehts dann auch. (also beim find fehlt das $dir nicht. man könnte es hinschreiben, ist aber unnötig. Da du so nur $(pwd) hinschreibst passiert nichts) Beide Lösungen haben aber den nachteil, dass sich sich nur für feste stellenanzahlen eigenen. Also wenn man das Problem 5 stufig hätte: 00001 bis 34546, so müsste man beide sachen 4 mal aufrufen (lassen). Grüße DaWi EDIT: Also man könnte es auch so machen:
for i in {1..5}
do
rename 's/file-(\d{$i})\.txt/file-0$1.txt/' *
done
|
Lux
Anmeldungsdatum: 10. November 2005
Beiträge: 5152
Wohnort: Grüt (Gossau ZH), Schweiz
|
DaWi hat geschrieben: for i in {1..5}
do
rename 's/file-(\d{$i})\.txt/file-0$1.txt/' *
done
Das geht nicht, da Variablen nicht innerhalb von einfachen Anführungszeichen substituiert werden. Gruss Dirk
|
Lutki
Anmeldungsdatum: 17. Juni 2006
Beiträge: 372
|
DaWi hat geschrieben: Beide Lösungen haben aber den nachteil, dass sich sich nur für feste stellenanzahlen eigenen. Also wenn man das Problem 5 stufig hätte: 00001 bis 34546, so müsste man beide sachen 4 mal aufrufen (lassen). EDIT: Also man könnte es auch so machen:
for i in {1..5}
do
rename 's/file-(\d{$i})\.txt/file-0$1.txt/' *
done
Das wird so nicht funktionieren. Wenn es funktionieren würde, hättest du aber nicht das Ergebnis, dass du haben willst. Da rename eh nur ein Perlskript ist, könntest du dir auch gleich etwas in perl bauen, so etwa: #!/usr/bin/perl -w
use strict;
if (!@ARGV) {
print "Error: no args!\n";
print "Usage: $0 /tmp/*.txt\n";
exit 1;
}
for (@ARGV) {
if (my ($a, $d, $z) = /^([^0-9]+)(\d+)(\S+)/) {
my $n = sprintf ("%0.5d", $d);
if (! -e "$a$n$z") {
rename $_, "$a$n$z" || warn "Warn: $!\n";
}
}
}
# eof Viele Wege führen nach Rom! ☺ MFG
|
JFG
Anmeldungsdatum: 17. September 2007
Beiträge: Zähle...
|
Ich würde wahrscheinlich auch in der Kommandozeile rename verwenden, je nachdem, welcher Gestalt die Dateien sind.. $ rename 's/-/-0/' file-?.txt Zum Beispiel ☺ Will ich dann doch noch eine Null bei allen dazu, führe ich es eben nochmal aus (Strg+p, Strg+w, file-*, Enter – oder: Strg+p, Alt+b, Strg+b, ?, Enter). Sowas braucht man ja nicht allzu allgemein zu halten, da es meist eh nur einmal gebraucht wird.. und ich glaube, ich wäre so recht schnell fertig ☺
|