Datei umbenennen, was mache ich falsch

T

tantor

Grünschnabel
Hallo zusammen,

ich würde gerne eine Datei umbenennen ,z.B.

y_url.o.lst.zip --> y_url_1.o.lst.zip

Wollte es wie folgt machen

Code:
echo ${y_url.o.lst.zip/.o./_1.o.}

aber ihc bekomme dann immer die Fehlermeldung

Code:
FSUM7728 bad ${} modifier

Kann wer helfen ?

Danke
 
1. Du öffnest viel zu viele Threads zum (im Grunde genommen) selben Thema.

2. zu y_url.o.lst.zip --> y_url_1.o.lst.zip
Code:
function get_new_filename {
    echo "$1" | sed -r 's/^([^\.]+)(.*)$/\1_1\2/g'
}

filename="y_url.o.lst.zip"
newfilename=$(get_new_filename "$filename")

mv "$filename" "$newfilename"

UNGETESTED!!!!!
 
hi,

@lfhelper
soweit ich weiss gibt es funktionen aber nur in der z-shell, die bash und die meisten anderen haben sowas meines Wissens nach nicht ;)

edit:
aber da waere es natuerlich mal wieder toll wenn der topic ersteller das mit angegeben haette...

mfg,
bytepool
 
Zuletzt bearbeitet:
1. NATÜRLICH hat die bash auch Funktionen.
2. Die angegebene Funktion ist imho völlig bloated für diese Aufgabe.
3. Der Threadersteller hats eigentlich schon fast richtig gemacht.
Probier mal statt:
Code:
echo ${y_url.o.lst.zip/.o./_1.o.}
einfach:
Code:
variable='y_url.o.lst.zip'
echo ${variable/.o./_1.o.}
Nennt sich ja nicht umsonst Variablenexpansion ;)
 
1. NATÜRLICH hat die bash auch Funktionen.

echt? Krass, wenn du das sagst glaub ich dir das mal, ist aber das erste mal dass ich das hoere...
Mhh, ich dachte ich haette Funktionen in der Bash mal kurz getestet und es hat nicht funktioniert... Ich glaub das geh ich jetzt direkt nochmal testen ;)

edit:
Tatsaechlich, funktioniert anstandslos, I stand corrected once again... Passiert mir irgendwie zu haeufig in letzter Zeit, werde wohl doch lieber haeufiger die Klappe halten statt hier falsche Informationen zu geben...

mfg,
bytepool
 
Zuletzt bearbeitet:
einfach:
Code:
variable='y_url.o.lst.zip'
echo ${variable/.o./_1.o.}

Dein Code (s/C/K/) ist einfach, aber nicht portabel. Für mich ist das Cryptocode.
(Cryptocode= man sieht nicht sofort was passiert. (ausser, und _nur_ ausser, man kennt die Bash) ).

Versuch mal dieselben Zeilen auf der ash, sh, psh, ksh, pdksh, csh, tcsh usw.

Mein Beispiel würde da auf mehr (möglicherweise nicht auf allen) Shells funktionieren.

Ich habe mir aus beruflicher Erfahrung so eine Schreibweise angewöhnt.

Schade, dass sie dir nicht gefällt.
 
Ifhelper schrieb:
Dein Code (s/C/K/) ist einfach, aber nicht portabel. Für mich ist das Cryptocode.
(Cryptocode= man sieht nicht sofort was passiert. (ausser, und _nur_ ausser, man kennt die Bash) ).

OMG.

Erstmal: das ist nicht mein code. Das ist quasi wortwörtlich der code vom Threadersteller, halt nur mit der Änderung, die ihn zum Funktionieren bringt.

Des Weiteren: da der Threadersteller diesen code verwendet, scheint es mir, dass er die bash verwendet und auch die Syntax dieser Variablen-Bearbeitung versteht. Also ist es für ihn (der anscheinend auch bash-Skripting lernen will) kein "Cryptocode".

Sorry, aber du machst dich echt ein Bisschen lächerlich hier. Du bezeichnest diese sed-like (variable/bla/blub, es fehlt nur das 's' und der terminierende slash, ansonsten VÖLLIG STRUKTURGLEICH) Variablenexpansion als "Cryptocode", und lieferst selber als Lösung für das Problem diesen sed-Ausdruck:
Code:
s/^([^\.]+)(.*)$/\1_1\2/g
Das muss man sich mal auf der Zunge zergehen lassen. Erstmal: das 'g' am Ende ist VÖLLIG absurd und redunant, wie sollen bitte mehrere Ausdrücke ersetzt werden, wenn du den Anfang und das Ende des Strings mitmatchst? 0o (^ und $)
btw sind diese Dinger auch völlig redundant in diesem Beispiel, denn die Quantifier in sed sind sowieso greedy, weshalb "per default" sowieso der gesamte String gematcht wird, aber egal, weiter im Text:
Statt EINFACH folgendes zu machen:
Code:
s#\.o\.#_1.o.#
also einfach die betreffende Stelle zu matchen und zu ersetzen, also quasi mit sed das zu machen, was der Threadersteller mit dem bash-buildin machen wollte und was somit auch ohne große regex-Kenntnisse recht verständlich gewesen wäre, machst du etwas völlig absurd verkomplizierendes, was den Ausdruck recht unlesbar, unübersichtlich und (für jemanden, der von regexes keine Ahnung hat) VÖLLIG unverständlich macht.
Du matchst alles bis vor dem ersten Punkt und speicherst es in der ersten backreference und dann matchst du alles ab dem ersten Punkt und speicherst dies in der zweiten backreference. Dann ersetzt du dies alles mit der ersten backreference, gefolgt von '_1' und darauf folgend die zweite backreference.
Dieser sed-Ausdruck sieht für mich so aus, als ob du dir die größte Mühe gegeben hättest cryptischen Code zu produzieren; und dann der Vorwurf an mich, LOL

Naja, ich geh jetzt mal auf Klo und kotze wegen irgendwas anderem…
 
Zuletzt bearbeitet:
@oben

Sorry, wir haben uns offensichtlich falsch verstanden.
Sed ist ein Standard. Viele Unix-like OS-User kennen das
und gehe mal einfach davon aus, dass jeder, der einigermassen
scripten kann es auch kennt. Leider kenn ich mich nicht mit
den Gegebenheiten jeder einzelnen Shell aus und beruflich bin
ich ganz, ganz woanders angesiedelt (wo es keine Bash gibt).
Zum "offline"-testen von Skripten habe ich es mir deswegen
angewöhnt Skripte so zu schreiben, dass sie (möglichst) auf
dem Server auf der Arbeit (ksh93), auf cygwin am Arbeitslaptop (bash) und
unter Linux (zsh im bash-mode @grml) auf der VMWare laufen.
In diesem Sinne musst du mein Codesnipplet äusserst abstrakt
betrachten. Die sed Zeile kann man zusammenfassen unter
"Sed wird hier benutzt." (mit was für ner regex auch immer).
Zu den Redundanzen würde ich sagen, ja, du hast recht.
Nur sed Zeilen schreibe ich (ausser wenns von der Logik her
nicht passt := eher selten) grundsätzlich mit s///g und erst
wenn das steht gehe ich mit den Cursortasten zurück und
befülle die Lücken. Ist so ein Habbitus. Aber mir ist schon klar,
dass es nicht notwendig wäre, das g am Ende. Stören tuts auch nicht.

Ich habe die Zeile blind und ungetestet einfach runtergeschrieben.

Funktionierts denn?

Mit "cryptisch" meine ich gerade so (IMHO) lexikalisch hässliche
Bash-internals wie die Varsubstitutionen, die möglich sind.*
* Zu meiner Verteidigung: nicht alle bash-builtins sind hässlich!

Klar, wenn du noch nicht einmal weisst, was sed oder ne regex ist,
dann hast du eh schlechte Karten, aber ich finde meinen Code trotzdem schöner.

Vielleicht ist es für den Kerl sogar besser er lernt sed als die paar bash-builtins.

Wollte dich nicht anpissen, ich dachte einfach es sei pedagogisch weniger hilfreich für ihn, diese bash-internals zu benutzen.

Peace! :headup:

EDIT:
Wir müssen aufpassen, weil wenn zwei sich streiten,
freut sich ein dritter, der herkommt, und dann gleich
ganz auf python oder perl setzt! ;-)
 
Zuletzt bearbeitet:
Viele Unix-like OS-User kennen das
und gehe mal einfach davon aus, dass jeder, der einigermassen
scripten kann es auch kennt.
lolol. Also kann man auch davon ausgehen, dass "unix-like os-user" alle perl können? 0o
In was für einer Welt lebst du eigentlich? 0o

BTW: du redest völlig am Thema vorbei, ich habe nicht deinen Einsatz von sed bemängelt, denn generell macht sed das ganze natürlich portabler, wobei ich nicht weiß, ob alle sed-Versionen auch die extended-regexes (also die '-r' Option) unterstützen. Könnte sein, dass das nur GNU sed, oder halt bestimmte sed Versionen können, womit man dann hier wieder vonwegen Portabilität rumnerven könnte, aber lassen wir das jetzt mal.

Es ging mir um deinen "Vorwurf", "Cryptocode" produziert zu haben o0
Das finde ich nach wie vor vollkommen absurd, wenn man sich deine "Lösung" ansieht. Denn diese ginge (auch mit sed) WESENTLICH einfacher und lesbarer. Und dann das Argument zu bringen, dass es pädagogisch wertvoll ist, sry, aber, omg, ich fall hier echt bald vom Stuhl…

Und dass das 'g' am Ende des sed-Ausdrucks "Niemanden stört" ist natürlich auch euphemisierend ausgedrückt Quatsch. Jedes Zeichen, dass der Threadersteller nicht kennt, muss er erst nachschlagen/nachgooglen/nachfragen, dadurch bringst du bei ihm nur tausend neue Fragen auf.

Ach und btw nochmal zum Thema "Cryptocode": wie ich bereits gesagt habe ist das erste '^' völlig unnötig. Also nehmen wir mal an, der Threadersteller wüsste nicht, was negierte Character-Classes sind und wüsste auch nicht, was "End of String" und "Beginning of String" Anchors sind, dann würde ihn dieser Anfang erstmal ziemlich ins Schleudern bringen, denn hier sind zwei gleiche Zeichen, die völlig verschiedene Bedeutung haben auf engem Raum zusammen verwendet:
Code:
^([^\.]+)
D.h. im Klartext: obwohl man das Caret am Anfang weglassen könnte und die regex genauso matchen würde, hast du es reingepackt und damit diese (für den Anfänger höchst verwirrende) Zweideutigkeit des Carets ins Spiel gebracht. (Und mir vorwerfen "cryptocode" zu produzieren…)

Ähnliches gilt für die Backreferences. Das ist eher ein "fortgeschrittenes" Thema in Bezug auf regexes und deine Verwendung packt dann zusätzlich auch noch wieder ein und dasselbe Zeichen auf engen Raum mit verschiedener Bedeutung:
Code:
\1_1
Woher genau, soll man denn wissen, dass die erste eins etwas VÖLLIG ANDERES bedeutet, als die zweite?

Ohne Witz, wenn mir jemand die Aufgabe gegeben hätte: Löse diese Aufgabe mit einer möglichst nicht nachvollziehbaren regex, ich hätte es wohl genauso wie du gemacht. Denn ohne Fortgeschrittene regex-Kenntnisse ist man bei deiner (höchst ungeschickten) regex wirklich aufgeschmissen.

Nochmal zum Mitschreiben und mit capslock, damit dus auch verstehst, respektive nicht wieder galant überliest: ES GEHT MIR NICHT(!!!!!!) UM DIE VERWENDUNG VON SED, SONDERN UM DIE KONKRETE UMSETZUNG.

Wir müssen aufpassen, weil wenn zwei sich streiten,
freut sich ein dritter, der herkommt, und dann gleich
ganz auf python oder perl setzt! ;-)
bla, hier gehts um shell-Skripte, dass sub-Forum für die angesprochenen Skriptsprachen findet sich eine Rubrik höher. (Wobei ich zugestehen muss, dass diverse perl-Codeschnipsel hier auch nicht völlig off-topic sind, aber egal…)

edit: nochmal in einem Satz: Dein sed-Ausdruck ist quasi der worst case in Bezug auf Anfängerfreundlichkeit/Lesbarkeit whatever. Wie gesagt, ich hätte es selbst mit der Intention etwas total kryptisches zu produzieren nicht schlimmer hingekriegt…
 
Zuletzt bearbeitet:
Jetzt krieg dich bitte wieder ein.

Ich habe dir keinen Vorwurf gemacht, echt nicht.

Lese meine Posts mal langsamer durch, ich habe alles auf die Varsubstitution geschoben (mit Begründung oder mindestens der Anmerkung, es sei meine Meinung), aber zu keinem Zeitpunkt auf dich persönlich.

Sorry, dass wir keine Freunde werden können.
 
Ich krieg mich ein, wenn mir danach ist. Und wenn du weiterhin darauf bestehst, dass
Code:
echo "$1" | sed -r 's/^([^\.]+)(.*)$/\1_1\2/g'
"weniger kryptisch"/einfacher/lesbarer etc. ist, als das hier:
Code:
variable='y_url.o.lst.zip'
echo ${variable/.o./_1.o.}
dann mach ich hier gleich ne Umfrage auf :|
 
Letztenendes gehts hierbei um Meinung gegen Meinung.

für mich steht da echo foo | sed bar.*
* und das ist einfacher als bash-varsubst, IMHO.

die variablensubstitution gefällt mir von der syntax und schreib/leseweise einfach nicht. Diese meinung habe ich geäussert.

Mehr ist nicht passiert.

Ich werde doch nicht die Welt auf den Kopf stellen,
um dich zufrieden zu stellen.

Meine regex ist super-complex, gebe ich zu.

Ausserdem:

teste mal die bash varsubst mit folgender Datei: y_url.o.o.o.o.lst.zip

Ich bleibe bei meiner Meinung, dass sed hier wohl besser wäre.**
** als ob man ds überhaupt festmachen könnte, was wirklich besser ist....
 
Zuletzt bearbeitet:
Ifhelper schrieb:
teste mal die bash varsubst mit folgender Datei: y_url.o.o.o.o.lst.zip
OMFG, BLA! Teste doch deinen sed-ausdruck mal mit ner versteckten Datei, also einer mit führendem Punkt… (Was wesentlich wahrscheinlicher ist, als dein seltsames Beispiel…)

Und btw, trotz capslock hast du den Schuss wohl immer noch nicht gehört:
Ifhelper schrieb:
Ich bleibe bei meiner Meinung, dass sed hier wohl besser wäre.
vs.
Gott_in_schwarz schrieb:
ES GEHT MIR NICHT(!!!!!!) UM DIE VERWENDUNG VON SED, SONDERN UM DIE KONKRETE UMSETZUNG.
Egal. I'm out. Ich bekomm Kopfschmerzen.
 

Ähnliche Themen

Verzeichnis mit 1200 Dateien auf Verweise in Textdateien checken

rsync Übertragung von Dateien zwischen zwei Servern

Wie sende ich eine Datei von Linux an einen eingesteckten Datenträger?

Skript soll nicht doppelt laufen... kill pkill pid cron

Komplette Spalten aus Datei löschen.

Zurück
Oben