• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[Gelöst] Bitte um Hilfe: Ein bestimmte Ausgabe zu erzielen::

Hinzu kommt noch das berühmte space-im-Dateinamen-Problem.
Ich weiß nicht: Tritt das überhaupt auf, wenn eine Datei pro Zeile gelistet wird wie mit "ls -1" ?
Wenn man das so wie in der oben geposteten for-schleife verarbeitet: Ja! Probier's aus ...

Wenn Leerzeichen enthalten sind kenne ich zwei Möglichkeiten

Entweder im Script den IFS ändern:
currentifs=${IFS} #IFS sichern,wird im Script überschrieben
IFS=$'\n'
lalalalal blabla usw
#schreibe ursprünglichen IFS zurück
IFS=${currentifs}

Oder

Einfach keine Leerzeichen haben oder füllen:
find -name "* *" | while read a ; do mv ${a} ${a//\ /_} ; done

Gruß Peter
 
trommelpeter schrieb:
Wenn Leerzeichen enthalten sind kenne ich zwei Möglichkeiten
oder einfach eine dritte:
Code:
for file in *
do
  echo $file
done
Man müsste eigentlich nur noch testen, was mit newlines im Dateinamen passieren würde ...
 
trommelpeter schrieb:
Hinzu kommt noch das berühmte space-im-Dateinamen-Problem.
Ich weiß nicht: Tritt das überhaupt auf, wenn eine Datei pro Zeile gelistet wird wie mit "ls -1" ?
Wenn man das so wie in der oben geposteten for-schleife verarbeitet: Ja! Probier's aus ...
Wenn Leerzeichen enthalten sind kenne ich zwei Möglichkeiten
Entweder im Script den IFS ändern:
currentifs=${IFS} #IFS sichern,wird im Script überschrieben
IFS=$'\n'
lalalalal blabla usw
#schreibe ursprünglichen IFS zurück
IFS=${currentifs}
Und was machst du wenn ein Newline im Dateinamen ist? Also nochmal... 8)
 
Hallo,

@Trommelpeter: Keine Sorge: Deine "find"-Version hatte ich mir schon angesehen und auch mal getestet :p. Ich fand sie aber nicht so ganz leicht zu verstehen, mit dem Formatstring und so. "-mtime" scheint mir laut "man find" auch irgendwie was anderes zu machen :?. Seltsamerweise weicht auch das Ergebnis von meinem Python-Ergebnis etwas ab. Schwer zu sagen, woran das liegt :roll:.

Insgesamt denke ich, die Schwierigkeit liegt wieder mal darin, daß es - zumindest mir - mit Bash Probleme bereitet, mehrzeiligen Output zu verarbeiten. Das hier geht zwar:
Code:
#!/bin/bash

find | while read i
do
    echo $i 
done
aber, wenn man zwischen "do" und "done" etwas einer Variablen zuweisen will (z.B. einem Array) ist diese oft außerhalb nicht mehr sichtbar (wegen Subshell). "{}" hilft da manchmal, aber nicht immer. Sehr unvorhersehbar das alles :x.

Ich hab' mein Python-Skript oben nochmal so geändert, daß der Name des Python-Skripts im Verzeichnis ignoriert wird und auch nur die Dateinamen ausgegeben werden. Zur Not kannst Du also aus Deinem Bash-Skript das Python-Skript aufrufen und seinen Output mit ">" in eine Datei Deiner Wahl leiten. Immerhin :wink:.

Viele Grüße
 
Code:
Diese Variable muss aber im nächsten Schritt gekennzeichnet werden:
$VARIABLE

Ah :)

Das war mir so nicht bewusst.

Vielen Dank! Wenn es nochmal wo hakt, dann frage ich hier nochmals. Ich möchte jetzt erstmal Zeit finden, das auch anzuwenden.

Vielen Dank nochmal!

Gruß

R
 
Also, damit es allen klar ist, ist hier nochmal ein Beispiel:
Code:
prompt> mkdir testdir
prompt> cd testdir
prompt> touch a "a a" "a
a"
prompt> LS_OPTIONS=-go
prompt> ls -1
-rw-r--r-- 1 0 May 15 03:16 a
-rw-r--r-- 1 0 May 15 03:16 a?a
-rw-r--r-- 1 0 May 15 03:16 a a
prompt> for file in `ls -1 a*`; do file "$file"; done
file: invalid option -- -w
...
prompt> LS_OPTIONS=""
prompt> for file in `ls -1 a*`; do file "$file"; done
a: empty
a: empty
a: empty
a a: empty
prompt> find . -name "a*" | while read file; do file "$file"; done
./a: empty
./a: empty
a: empty
./a a: empty
prompt> for file in a*; do file "$file"; done
a: empty
a
a: empty
a a: empty
prompt>
Nur die letzte Möglichkeit liefert ein komplett richtiges ergebnis. Als Alternative ginge auch find -exec oder find ... xargs

python und perl sind natürlich aufgrund der besseren Sortiermöglichkeiten natürlcih gut geeignet. Eine reine bash-Lösung geht sicher auch irgendwie, aber da muss ich nochmal separat Zeit investieren...
 
A

Anonymous

Gast
notoxp schrieb:
Nur die letzte Möglichkeit liefert ein komplett richtiges ergebnis. Als Alternative ginge auch find -exec oder find ... xargs

Ich wills jetzt gar nicht ausprobieren ( weil so was hat sowieso kein vernünftiger Mensch als Dateien auf dem Rechner) aber wenn wir hier weiterspinnen und Filenamen anlegen zB in dieser Art hier:
Code:
> " ; exit ; "
> " $PATH "
> "-minus"
> "1<$2 &"
> " {[*?\; " ' | :() "

und mit noch blöderen Sonderzeichen werden hier in der Bash irgendwann einmal sämliche Versuche ein einziges Script zu schreiben, dass alle eventuellen Möglichkeiten richtig bearbeitet, scheitern. Die meiste Resistenz gegen solche Datein hat wohl find, aber auch die kompliziertesten Möglichkeiten sowas an mehrere Befehle zu übergeben.

Wir sollten mal auf dem Teppich bleiben und uns auf die Einstellungen beschränken die default jeder auf dem REchner hat, und mit solchen Dateinnamen befassen wie sie ein normaler Mensch anlegt, denke ich. Weil, sonst verscheuchen wir hier jeden Neuling der hier mal vorbeischauen will um sich mit der Konsole zu befassen.

robi
 
robi schrieb:
Ich wills jetzt gar nicht ausprobieren ( weil so was hat sowieso kein vernünftiger Mensch als Dateien auf dem Rechner)
Dateinamen mit spaces hat keiner? ;)
Was das Newline betrifft ist das eventuell sogar richtig, aber auf ähnliche Weise entstanden in der Vergangenheit selbst bei renommierten Softwarehäusern viele Sicherheitslöcher. Gerade deine Beispiele mit exit usw. wären ja eine Form von code injection...
Wir sollten mal auf dem Teppich bleiben und uns auf die Einstellungen beschränken die default jeder auf dem REchner hat, und mit solchen Dateinnamen befassen wie sie ein normaler Mensch anlegt, denke ich. Weil, sonst verscheuchen wir hier jeden Neuling der hier mal vorbeischauen will um sich mit der Konsole zu befassen.
Es ist doch in diesem Fall nicht so schwer. Wir formulieren einfach den Merksatz: Verwende statt for ... in `ls`... lieber find
... und fertig ist die Laube.

Aber der eigentliche Grund für das aufblähen dieses Threads ist aus meiner Sicht, weil einige Fortgeschrittene den oben genannten Merksatz anzweifelten. Ich sehe es so: Auf Nachfrage (und die wurde eindeutig gestellt) liefer ich gerne die Gründe dafür, sofern ich mit der Materie vertraut bin. Das finde ich persönlich gar nicht so schlecht. So haben alle etwas davon - nicht nur die Neulinge. Und so wurden auch Denkfehler auf meiner Seite bereinigt...
 
Hallo zusammen

Ich fühle mich im Moment wie von Seite 1000 auf Seite 10 zurückgeworfen. Ich dachte immer ich hätte alles halbwegs verstanden was ich in "Shell-Script Programmierung" von Patrick Ditchen gelesen habe. Allerdings geht er auch nicht von Profi-Fällen aus mit denen ein Anfänger sowieso nie in Berührung kommt. Bei dem klingt alles noch viel einfacher und nachvollziehbarer und in kleine Lernhäppchen aufgeteilt.

Im Moment stehe ich bisschen auf der Leitung.

Was mein Lösungsvorschlag anbelangt: den habe ich ausgeknobelt.
Meine Idee war das die Reihenfolge stimmt. Den find liefert meist eine sehr chaotische Reihenfolge. So kam mir die Idee das ich mit der Ausgabe erstmal Tag des Jahres, Stunde Minute Sekunde voranstelle.
Dann wird sortiert.
Wenn alles erledigt ist schneide ich alles was ich nicht mehr brauche wieder weg ( cut -c 11- ) .
Wenn ich irgendwo einen Konzentrationsfehler oder einen Denkfehler dabei habe lasse ich mich aber gerne im Detail aufklären was da kongret falsch ist. Ich glaube das ich dann noch am meisten kapiere.
Weil dieses verzetteln in tausend Spezialfälle verwirrt mich etwas.
(Betreff konzentrationsfehler: es passiert mir garnicht so unselten das sich in meine Scripte ein völlig dämlicher Fehler einschleicht wo ich mir nach endlosen suchen selber an die Stirn greife :) . )


Gruß Peter
 
trommelpeter schrieb:
Ich fühle mich im Moment wie von Seite 1000 auf Seite 10 zurückgeworfen.
So schlimm ist es nicht... :wink:

So kam mir die Idee das ich mit der Ausgabe erstmal Tag des Jahres, Stunde Minute Sekunde voranstelle.
[...]
Wenn ich irgendwo einen Konzentrationsfehler oder einen Denkfehler dabei habe lasse ich mich aber gerne im Detail aufklären was da kongret falsch ist.
Die Idee ist doch nicht schlecht. Dein Vorschlag war:
Code:
for datei in `find ~/dein/Pfad/ -mtime -10 -printf "%Aj%AH%AM%AS %p\n" | sort -u | tail -n 10 | cut -c 11-` 
do
Lege mal eine Datei mit einem Leerzeichen im Namen an und teste, was passiert. Eine Datei Namens "bla laber" würde als zwei Dateien interpretiert werden. Lösung (sofern man das Newline-Problem vernachlässigt):
Code:
find ... | while read $datei
EDIT: richtig wäre natürlich ohne Dollar vor datei, also:
Code:
find ... | while read datei
 
Ich glaube ich begreife langsam. Du hast recht wenn du lieber die
while read-Schleife vorschlägst.
Aber dann habe ich noch eine kleine Ergänzung um das Leerzeichenproblem sicher in Griff zu bekommen:

Code:
find ... | while read "$datei"

"" die sind nötig das eine Datei mit Leerzeichen dann sicher als zusammenhängend erkannt wird.

Gruß Peter
 
trommelpeter schrieb:
Code:
find ... | while read "$datei"

"" die sind nötig das eine Datei mit Leerzeichen dann sicher als zusammenhängend erkannt wird.
Hier habe ich in der Eile etwas falsches gepostet :oops: . Es muss natürlich heißen while read datei (also ohne Dollar). Im do-teil kommt dann das dollar mit doppelten Hochkommas zum Einsatz...
 
Also ich hoff das nehmt ihr mir jetzt nicht übel, aber das Erfordernis für den Script hat sich gelöst.

Ich darf quasi einen priviligierten Samba user anlegen, der die Arbeit auch beaufsichtigt übernehmen soll.

Dann wird die Werbung die durchaus mal zwischendrin ist nicht mit ausgedruckt. (Administrative Richtlinie quasi).. Sicher ist die problematik bekannt.

Vielen Dank an euch! Habe etwas dazugelernt und werde davon weiter profitieren es kann aber durchaus passieren, dass ich nochmal was zum Thema for schleife fragen werde. Vielleicht mach ich den Script aus dem Grund noch fertig. Des verständnisses halber.

Gruß

R
 
Oben