[linux-l] shell skript probleme mit leerzeichen

Jan-Benedict Glaw jbglaw at lug-owl.de
Do Okt 27 20:32:32 CEST 2005


On Thu, 2005-10-27 17:42:40 +0200, willek <willek at gmx.de> wrote:
> Jan-Benedict Glaw schrieb:
> [Dein skript]
> >>Danke, das funktioniert, obwohl ich nicht verstehe warum. Warum reicht
> >>in diesen Fall ein Stern aus, um alle Dateien einzulesen?
> > Ja.
> Naja, das es funktioniert hab ich gemerkt. Warum funktioniert es? Warum
> steht der Stern für alle Dateien im aktuellen Verzeichnis, und nicht für
> stdin oder weiss der Himmel was?

Warum ist zwei die nächste ganze Zahl nach der eins?

In der shell gibt es ein Feature, daß sich "globbing" nennt. Das
funktioniert nach Mustern, die ähnlich z.B. auch von DOS kopiert
worden waren.

"*" steht für alle Dateien, Verzeichnisse etc., die nicht mit einem
	Punkt anfangen (das wären dann "versteckte" Dateien.)
"?" steht für ein beliebiges Zeichen und kann kombiniert werden

Damit kann man dann so Sachen wie

	*.jpg
	a*.jpg
	a???.jpeg

etc. machen.

> >>for i in `ls |sed s/" "/"\\ "/g` ; do
> >>warum hat das nicht funktioniert?
> > Oha... Lieber nicht anfangen, irgendwelche Spezialfälle speziell zu
> > behandeln. Was ist, wenn Dateinamen einen Zeilenumbruch beinhalten?
> > Maskierst Du den dann auch?
> 
> Du hast ja recht. Aber die Frage bleibt: wenn ich die Leerzeichen so
> maskieren will, warum funktioniert das nicht? $i sollte doch dann

...weil im Kontext der shell die \\ zu einem \ zusammengezogen werden
(Stichwort "quoting"). Ein \ (das dann noch bei sed ankommt) hat wiederum
für sed besondere Bedeutung, sodaß es mit dem folgenden Leerzeichen
zusammen ausgewertet wird. Richtig wäre also:

	ls | sed s/" "/"\\\\ "/g

Um das lesbarer zu gestalten, würde man das aber vermutlich eher so
schreiben:

	ls | sed 's/ /\\ /g'

Das funktioniert eingesetzt aber immernoch nicht wirklich; verdoppelt
man die backslashes nochmal, so wird ein backslash ausgegeben, aber
das Leerzeichen ist immernoch ein Trennzeichen :-/

> > Da gibts mehrere Wege. Entweder checkst Du den file type:
> > 
> > for i in *; do
> > 	case `file -b "$i"` in
> > 		*image*)
> > 			IMAGE_BASENAME="${i%.*}"
> > 			convert -resize 640x480 "$i" "verkleinert/${IMAGE_BASENAME}.$1"
> > 			;;
> > 		*)
> > 			:;;
> > 	esac
> > done
> 
> Das ist schön, einfach und nett. Das werde ich erstmal genau so übernehmen.

Das ist übrigens nicht getestet, ein Testlauf tut also gut :-)

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw at lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 für einen Freien Staat voll Freier Bürger"  | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : signature.asc
Dateityp    : application/pgp-signature
Dateigröße  : 189 bytes
Beschreibung: Digital signature
URL         : <https://mlists.in-berlin.de/pipermail/linux-l-mlists.in-berlin.de/attachments/20051027/e7ee565e/attachment.sig>


Mehr Informationen über die Mailingliste linux-l