[Frage] - Cronjob-Befehle funktionieren nicht

Status
Für weitere Antworten geschlossen.

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
1. /volume1/public/mv.sh erstellen
Code:
#!/bin/sh
mv "$[COLOR="red"]1[/COLOR]" "${[COLOR="red"]1[/COLOR]#canon-}"
2. rm.sh erstellen
Code:
#!/bin/sh
#
find /volume1/Video/ -name 'canon*.*' -exec /volume1/public/[COLOR="red"]mv[/COLOR].sh '{}' \;

Eigentlich hatte ich das ja schon vorgeben ... das war die Idee ... ich habs aber nicht getestet ... kann also noch Fehler enthalten

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
@itari
Habe deinen Code mal probiert, aber beim mv sind Quelle und Ziel immer identisch. Kannst du mir mal (am besten Dummy sicher) erklären was ${1#canon-} machen soll? Heisst dies von $1 alles ohne canon- ausgeben? Wofür steht denn # in diesem Zusammenhang? Für Ignorieren?
Ich frag so blöd weil merthos mir heute auch so eine elegante Lösung für mein awk-Vorhaben präsentiert hat. Kannte diese "Art" des Codes gar nicht.
Danke für die Aufklärung oder einen guten Link ;)

Gruss

tobi
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
So anhand dieser Seite (http://www.linuxjournal.com/article/8919) habe ich mir einen kurzen Crash-Kurs verpasst. ;-)
@itari dein Code geht bei mir nur wenn ich
Code:
mv "$1" "${1#*canon-}"
mache.
Und das haut mir dann logischerweise die Pfade klein, wenn ich den find mit einem absoluten Pfad laufen lasse.
Code:
mediaserver> find /volume1/public/test -name 'canon-*' -exec /root/test_itari.sh '{}' \;
/volume1/public/test/canon-test1.jpg test1.jpg
/volume1/public/test/canon-test2.jpg test2.jpg
/volume1/public/test/canon-test3.jpg test3.jpg
Der * ist anscheindend nötig weil find die Datei immer als ./datei liefert auch wenn find ohne jegliche Pfadangabe laufen gelassen wird. Dein Code dürfte auch Probleme bekommen wenn der find in die Tiefe geht bzw der Code hat keine Probleme, aber das Ergebnis dürfte nicht im Sinne des Erfinders sein ;-)
Code:
mediaserver> find -name 'canon-*' -exec /root/test_itari.sh '{}' \;
./test/canon-test1.jpg test1.jpg
./test/canon-test2.jpg test2.jpg
./test/canon-test3.jpg test3.jpg
 

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Danke für die Korrektur. Ich hatte ja schon geschrieben, dass ich das nicht getestet habe. Ich hab das einfach nur blind aus dem Post #10 übernommen.

Itari
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Guten Morgen,

ich such und probier mir jetzt schon bestimmt ne halbe Std. nen Wolf, bekomms aber selbst nicht gebacken, wie ich mehrere find und mv awk Befehle in einem Shell-Script nacheinander ausführen kann. Ist bestimmt ne simple Sache, aber so ganz ohne Ansatz ....

Edit: muss ich evtl. mit if fi else arbeiten?

Und dann hab ich noch ne Verständnisfrage zu
Code:
#!/bin/sh
for f in $(find /volume1/public/test -type f -name "*-canon*")
do
  echo "$f" $(echo $f | awk -F"-canon" '{print $1}')".${f##*.}"
done
Warum wird hier kein Semikolon vor u.a. do oder done gesetzt?
 
Zuletzt bearbeitet:

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Rich (BBCode):
#!/bin/sh
for ...
do
 ...
done
for ...
do
 ...
done

ist jetzt nicht das, was du suchst?

Warum wird hier kein Semikolon vor u.a. do oder done gesetzt?

wegen der Zeilenvorschübe

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
@Binomico
Wie tari bereits sagte einfach mehrere Schleifen nacheinander laufen lassen. Das geht problemlos, habe ich mit meinem Testcode auch gemacht. Insgesamt brauchte ich 4 Schleifen um alle Fälle abzudecken
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Doch eigentlich schon, das war mein erster Ansatz, aber dann bekomm ich die Meldung

mv: can't rename 'dateinamen.dateiendung': No such file or directory
.
.
.
Hab den "Fehler" gefunden! Ein Leerzeichen im Ordnername war die Ursache für obige Fehlermeldung und das beste daran, das ist der Einzige (mit Leerzeichen) und genau auf diesen, respektive dessen Inhalt, hab ich meine Tests beschränkt :D

wegen der Zeilenvorschübe
Sprich wenn ich den Codeschnipsel ohne Einschübe speichern würde, könnte/müsste ich Semikola einfügen, richtig?

Was müsste ich ändern, wenn die Groß- und Kleinschreibung nicht beachtet werden soll? ein -iname hat nicht funktioniert.

Gibt es auch eine ähnliche Variante, um Buchstaben innerhalb eines Dateinamens zu löschen (bitte hier - besser generell :D - blos kein Stress, ich hab jetzt was ich benötige, rein Interessehalber, man weiß ja nicht, wanns mal nützlich sein kann)?

Cheers
 
Zuletzt bearbeitet:

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
Du kannst awk ja auch an einer Buchstabenfolge den String teilen lassen. Damit ist die Buchstabenfolge dann nicht mehr im String und damit eigentlich gelöscht
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Mir fehlt hier im Forum eindeutig ein Beitragsdanke-Hack oder ähnliches (wurde das nicht mal ausdiskutiert? Und was ist daraus geworden, aus administrativer Sicht?) :D

Nun leider bin ich bei solch kryptischen Scripten nicht bewandert genug, um diese zu verstehen; aber falls euch mal etwas langweilig ist und ihr gerade Bock drauf habt, könntet ihr mir anhand von aktuellem Beispiel die Funktionsweise etwas näher bringen :) (mit den online Tutorials komm ich echt nicht weiter)

z.B. was definiert for f in? find ist denk ich klar, -type auch, name auch, nur der Parameter nach name nicht ganz (kann ich hier z.B. "*irgendwas*.*" angeben, damit mitten im Dateinamen gesucht wird?), echo gibt das ganz nur aus und macht keine Änderungen, richtig? Nach echo versteh ich dann nur noch garnüschts ...^^

for f in $(find /volume1/public/test -type f -name "canon-*")
do
echo "$f" $(echo $f | awk -F"canon-" '{print $1 $2}')
done

Cheeeeerio
 

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
for i in "a" "b" "c"
do
echo $i
done

Die Shell-Variable 'i' wird nacheinander die Texte "a", "b" und "c" annehmen und der echo gibt dann den Inhalt von "i" indem man ein "$" davor setzt; alternativ kann man auch ${i} schreiben.

$(find /volume1/public/test -type f -name "canon-*")

Das Tool 'find wird auf das Verzeichnis "/volume1/public/test" gestellt und arbeitet rekursiv alle Unterverzeichnisse ab, wobei die Namen von Dateien (-type f) und dem Dateinamen (-name) welche mit 'canon-' anfangen, ausgegeben werden. Das '*' (Sternle) bedeutet: hier kann (muss aber nicht) eine beliebige Zeichenfolge stehen. Die $(...)-Klammerung bedeutet, dass dieses Kommando ausgeführt werden soll und die Ausgabe des Kommandos an diese Stelle substituiert werden, an der das Kommande selbst stand.

echo $f

Gibt den Inhalt der Shell-Variable "f" aus

$(echo $f | awk -F"canon-" '{print $1 $2}')

Die Ausgabe von echo $f wird durch das "|" (pipe) zur Daten-Eingabe des awk. Der awk bekommt seine Steueranweisung durch die Option '{print $1 $2}'. Damit die Shell nicht an die '$'-Zeichen für Shell-Variablen herankommt, wird das Ganze per " ' " (single quote) geschützt. Die Anweisung {print $1 $2} für den awk bedeutet, dass pro Eingabezeile diese Aktion {....} ausgeführt wird und zwar sollen die Felder 1 und 2 ausgeben werden (print). Voreingestellt als Feldtrennzeichen ist die Leerstelle oder der Tabulator oder eine beliebige Kombination von beiden hintereinander. Damit aber das gewünschte Resultat eintritt, wird diese Konvention durch die Option '-F' (Field-Delimiter) ausgetauscht gegen den Text 'canon-'.

Das Ergebnis hätte man auch durch eine andere Art von Kommandos oder durch eine andere Aufbereitung von Optionen erzielen können. Mit anderen Worten, dies ist weder die einfachste Lösung noch die einzigste. Das schon mal vorweg zu deiner Frage, hätte es man nicht auch so oder so machen können. In der Skript-Programmierung ist es wie bei Rechnen, es gibt unendlich viele Wege zu einem richtigen oder falschen Ergebnis zu kommen.

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
@itari
hut ab für diese ausführliche Erklärung. Verständlicher als jedes Manual und Wiki ;-)
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Meine Lobeshymnen auf itari wurden dank der Performance-Schwäche nicht übertragen, drum kurz und knapp

Alter, ich verneige mich und sage dankeschön :)
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Hi,

erste Erfolgsmeldung aus der Praxis!

Nur wenn ich Teile im Dateinamen ersetzen möchte und die Groß- u. Kleinschreibung nicht beachtet werden soll, bekomm ich eine Fehlermeldung "Invalid argument", ich geh davon aus, dass -iname für die Suche richtig gesetzt ist und -type d für Ordner auch stimmt.

#!/bin/sh
for f in $(find /mein/pfad -type d -iname "*suchbegriff*")
do
mv "$f" $(echo $f | awk -F"suchbegriff" '{print $1 $2}')
done


Edit: ich hab grad nach ".." suchen lassen und wollte als Resultat ".", allerdings wurden mir jetzt Teile nach ".." abgeschnitten :confused:


#!/bin/sh
for f in $(find /mein/pfad -type d -name "*..*")
do
mv "$f" $(echo $f | awk -F"." '{print $1 $2}')
done
 
Zuletzt bearbeitet:

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Hinweis zu Tools wie 'find'. Stell dir vor, 100.000 Leute hätten sich ihr eigenes Word unter Windows geschrieben, alle ein wenig anders, aber sie bezeichnen es alle als 'Word' und du musst jedesmal ausprobieren, was dein Word kann oder auch nicht. Du hast aber immer die Möglichkeit, dir ein anderes Word (zusätzlich) zu installieren oder dir ein eigenes zu schreiben. Verrückte Sache, nicht?

Aber genauso ist es bei Linux/Unix der Fall. Du musst jedesmal ausprobieren, ob etwas geht oder nicht und dir dann eventuell ein anderes (gleichnamiges) Tool installieren, was du per IPKG in ausreichendem Maße tun kannst. Also wenn der eingebaute Busybox-find die Option -iname nicht kennt, dann musste mal schauen, ob du dir nicht einen IPKG-find installieren magst.

Tipp für die Geschichte mit dem '..': lass den find doch ohne den Rest einmal suchen, dann wird dir angezeigt, ob es Fehler gibt oder etwas anderes gefunden wird, als du denkst. Manchmal muss man auch eine wenig mit den '*' spielen oder schauen, ob der '.' auch nicht als Metazeichen interpretiert wird und deswegen noch einen '\' davor braucht, damit er auch nur als Punkt verstanden wird.

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
Wie genau hat denn so ein Testverzeichnis mit .. im Namen ausgeschaut? Und was willst du denn überhaupt find(en)? Dateien oder Vezeichnisse?
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Vorweg, ich spiel gerade nur mit den Befehlen, um sie besser zu verstehen ... :)

1. ich hab ein Ordner angelegt Bilder.Urlaub.Schweiz
2. nach "*Urlaub*" gesucht und dies eliminieren lassen (fälschlicher weise nicht nach "*Urlaub.*" oder "*.Urlaub*" ... hat funktioniert
3. hab ich nach "*..*" gesucht (konkret "Bilder..Schweiz", um obigen Fehler bereinigen zu lassen, hier wurde alles nach ".." entfernt (konkrete Ausgabe "Bilder")
Ein Test mit folgendem Script hat nichts anderes ausgegeben

#!/bin/sh
for f in $(find /volume1/test/ -type d -name "*..*")
do
mv "$f" $(echo $f | awk -F"\." '{print $1 $2}')
done

Zur Groß- und Kleinschreibung:
Die Suche mit -iname funktioniert perfekt, nur AWK benötigt bestimmt einen Operator, welcher klarmacht, dass die Gross- und Kleinschreibung keine Rolle spielt. Hab hier nur http://www.unix.com/shell-programming-scripting/31078-awk-case-insensitive.html gefunden, wie und ob das über haupt Sinn macht ...

#!/bin/sh
for f in $(find /volume1/test/ -type d -iname "*urlaub*")
do
mv "$f" $(echo $f | awk -F"urlaub" '{print $1 $2}')
done

mv -i oder awk -i hauen nicht hin ... aber das wär ja auch zu einfach :D
 

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Die nächste Frage ist bestimmt einfacher :D

Ich würde gern rekursiv in allen Datei - und Ordnernamen "-" durch "." ersetzen.

#!/bin/sh
find /volume1/mein/Verzeichnis -name "*-*" -exec rename 's/-/./g' '{}' \;

Ergebnis find: rename: no such file or directory
Ein find /volume1/mein/Verzeichnis -name "*-*" liefert zumindest mal alle Treffer, nur die Übergabe an rename, da haperts.

Edit: hab was gefunden und zusammengebastelt, das funktioniert (allerdings kommen ein paar Fehlermeldungen, trotz korrekter Umsetzung - ich glaub move mag es nicht, wenn eine Bedingung auf den Ordner und das/die darin liegende(n) file(s) zutrifft Edit: ist ja logisch! Es wird gesucht, dann der Ordner umbenannt und jetzt trifft der zuvor gefundene Pfad, zum Ändern der Datei nicht mehr zu, da umbenannt ... richtig wäre also erst einmal die Dateien -type f zu suchen und umzubenennen, dann die Ordner -type d :)

#!/bin/sh
find /volume1/mein/Verzeichnis/ -name "*-*" -print | while read file
do
new=`echo "$file" | sed 's/-/./g'`
mv "$file" "$new"
done


Zu meinem obigen Erklärungsversuch, eigentlich sollte doch zuerst -type f abgearbeitet werden und dann -type -d, aber ich muss für korrekte Ergebnisse das Script zweimal laufen lassen (wenn eine Datei und ein Verzeichnis - im Namen enthalten ?
Wäre es eine Lösung, zuerst -type f abzuarbeiten und dann den Zweiten Befehl in ein separates Script zu stecken, welches durch ersteres aufgerufen wird? Edit: nö, leider nicht

#!/bin/sh
# search for files
find /volume1/mein/Verzeichnis/ -type f -name "*-*" -print | while read file
do
new=`echo "$file" | sed 's/-/./g'`
mv "$file" "$new"
done
# search for folders
find /volume1/mein/Verzeichnis/ -type d -name "*-*" -print | while read file
do
new=`echo "$file" | sed 's/-/./g'`
mv "$file" "$new"
done

itari schrieb:
Hinweis zu Tools wie 'find'. Stell dir vor, 100.000 Leute hätten sich ihr eigenes Word unter Windows geschrieben, alle ein wenig anders, aber sie bezeichnen es alle als 'Word' und du musst jedesmal ausprobieren, was dein Word kann oder auch nicht. Du hast aber immer die Möglichkeit, dir ein anderes Word (zusätzlich) zu installieren oder dir ein eigenes zu schreiben. Verrückte Sache, nicht?

Aber genauso ist es bei Linux/Unix der Fall.
BINGO :D hätte meine vorherigen Fragen ebenso mit diesem Script lösen können. Aller Anfang ist schwer, aber mit kleinen Schritten gehts voran ...

Gruß

Edit: Groß- und Kleinschreibung gelöst. Langsam fang ich an zu jubeln :D


#!/bin/sh
# search for files
find /volume1/mein/Verzeichnis/ -type f -iname "*urlaub-*" -print | while read file
do
new=`echo "$file" | sed 's/[Uu][Rr][Ll][Aa][Uu][Bb]-//g'`
mv "$file" "$new"
done
 
Zuletzt bearbeitet:

Binomico

Benutzer
Mitglied seit
01. Jun 2010
Beiträge
573
Punkte für Reaktionen
0
Punkte
42
Bing Boom Badabeng!
Ich würde gern rekursiv in allen Datei - und Ordnernamen "-" durch "." ersetzen.

#!/bin/sh
find /volume1/mein/Verzeichnis -name "*-*" -exec rename 's/-/./g' '{}' \;

Ergebnis find: rename: no such file or directory
Ein find /volume1/mein/Verzeichnis -name "*-*" liefert zumindest mal alle Treffer, nur die Übergabe an rename, da haperts.
Nach ipkg install perl-file-rename klappt auch das :D (in itaris Link war der Hinweis)

Momentan versuch ich den ersten Buchstaben aller Dateinamen von klein in GROSS zu ändern

#!/bin/sh
find /volume1/mein/Verzeichnis/ -name "*.*" -print | while read file
do
new=`echo "$file" | sed 's/\(^[a-z]\)/\U/g'`
mv "$file" "$new"
done
 
Zuletzt bearbeitet:
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat