Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(Bash) Leerzeichen in for-Schleife maskieren

175 views
Skip to first unread message

Thomas Wildgruber

unread,
Nov 17, 2012, 6:56:47 AM11/17/12
to
Hi Group,

um mir mal schnell einen �berblick �ber die Gr��en einiger Verzeichnisse
anzeigen zu lassen, habe ich das 'du -hs' Kommando in einer for-Schleife
laufen lassen aber bei Verzeichnissen mit Leerzeichen scheitert das
Vorgehen und das maskieren der Leerzeichen mit G�nsef�sschen funktioert
nicht:

---snip---
$ ls -l
total 0
drwxr-xr-x@ 14 pronto staff 476 4 Sep 2011 DP4Lion.vmwarevm
drwxr-xr-x@ 18 pronto staff 612 1 Nov 11:34 Debian 5.vmwarevm
drwxr-xr-x@ 17 pronto staff 578 4 Sep 2011 Debian 5_3.vmwarevm
drwxr-xr-x@ 42 pronto staff 1428 3 Feb 2012 Debian_6.0.0_GUI.vmwarevm
drwxr-xr-x@ 50 pronto staff 1700 10 Nov 12:05 Debian_6_1.vmwarevm
drwxr-xr-x@ 18 pronto staff 612 17 Nov 12:06 MacOS_Lion_1.vmwarevm
drwxr-xr-x@ 84 pronto staff 2856 1 Sep 13:06 W2K8R2_1.vmwarevm
drwxr-xr-x@ 60 pronto staff 2040 2 Jun 20:35 Windows 7.vmwarevm
drwxr-xr-x@ 122 pronto staff 4148 17 Nov 12:08 Windows XP
Professional.vmwarevm
---snap---

---snip---
$ for i in `ls`; do du -hs "$i"; done
9,3G DP4Lion.vmwarevm
du: Debian: No such file or directory
du: 5.vmwarevm: No such file or directory
du: Debian: No such file or directory
du: 5_3.vmwarevm: No such file or directory
5,6G Debian_6.0.0_GUI.vmwarevm
11G Debian_6_1.vmwarevm
14G MacOS_Lion_1.vmwarevm
32G W2K8R2_1.vmwarevm
du: Windows: No such file or directory
du: 7.vmwarevm: No such file or directory
du: Windows: No such file or directory
du: XP: No such file or directory
du: Professional.vmwarevm: No such file or directory
---snap---

Jetzt habe ich gelesen, dass man den Internal Field Seperator (IFS) zB auf
ein Nemwline-Ziechen (\n) setzen k�nnte aber das scheint nur in Skripts
oder Shellfunktionen zu funktionieren:

---snip---
$ foldersize ()
> {
> IFS=$'\n'
> for i in `ls`; do
> du -hs $i
> done
> }
---snap---

Diese Funktion liefert dann die erwartete Ausgabe:

---snip---
$ foldersize
9,3G DP4Lion.vmwarevm
2,0G Debian 5.vmwarevm
7,1G Debian 5_3.vmwarevm
5,6G Debian_6.0.0_GUI.vmwarevm
11G Debian_6_1.vmwarevm
14G MacOS_Lion_1.vmwarevm
32G W2K8R2_1.vmwarevm
25G Windows 7.vmwarevm
50G Windows XP Professional.vmwarevm
---snap---

Jetzt habe ich aber das a) das Problem, dass zumindest in dieser Shell
hinterher meine Umgebungsvariable IFS nicht mehr stimmt, was noch zu
verschmerzen w�re (weil nur f�r diese Shell g�ltig) und b) ich es jetzt
nicht hinbekommen habe das Setzen der Umgebungsvariable in meinem Quick and
Dirty Einzeiler Workaround zu integrieren.

Ein Setzen der Umgebungsvariable in einem Einzeiler scheitert:

---snip---
$ IFS=$'\n' for i in `ls`; do du -hs "$i"; done
-bash: syntax error near unexpected token `do'
---snap---

Kann man jetzt in dieser for-Schleife die Leerzeichen irgendwie geschickt
maskieren, so dass das Kommando als Einzeiler ausgef�hrt werden kann oder
brauche ich die umst�ndliche Variante mit Shell-Skript oder -Funktion?

Thx & Bye Tom
--
"Manches Gewissen ist nur rein, weil es nie benutzt wurde" (Robert Lembke)

Thomas 'PointedEars' Lahn

unread,
Nov 17, 2012, 9:11:06 AM11/17/12
to
[X-Post & F'up2 de.comp.os.unix.shell]

Thomas Wildgruber wrote:

> Jetzt habe ich gelesen, dass man den Internal Field Seperator (IFS) zB auf
> ein Nemwline-Ziechen (\n) setzen könnte

Richtig.

> aber das scheint nur in Skripts oder Shellfunktionen zu funktionieren:

Natürlich, es ist eine *Shell*variable.

> ---snip---
> $ foldersize ()
>> {
>> IFS=$'\n'
>> for i in `ls`; do
>> du -hs $i
>> done
>> }
> ---snap---
>
> Diese Funktion liefert dann die erwartete Ausgabe:
> […]
> ---snap---
>
> Jetzt habe ich aber das a) das Problem, dass zumindest in dieser Shell
> hinterher meine Umgebungsvariable IFS nicht mehr stimmt, was noch zu
> verschmerzen wäre (weil nur für diese Shell gültig)

Du kannst den Wert von IFS sichern und wiederherstellen:

IFS_bak=$IFS
IFS=$neuer_Wert

# tu was

IFS=$IFS_bak

> und b) ich es jetzt nicht hinbekommen habe das Setzen der
> Umgebungsvariable in meinem Quick and Dirty Einzeiler Workaround zu
> integrieren.
>
> Ein Setzen der Umgebungsvariable in einem Einzeiler scheitert:
>
> ---snip---
> $ IFS=$'\n' for i in `ls`; do du -hs "$i"; done
> -bash: syntax error near unexpected token `do'
> ---snap---

`for' ist kein Befehl und hat daher kein eigenes Environment. Deshalb
funktioniert das so nicht. Siehe Abschnitt SHELL GRAMMAR/Simple Commands in
bash(1).

Dein Ansatz ist aber bereits fchsal. Command Substitution (`…` bzw. $(…)`
konvertiert alle Whitespaces in der Ausgabe des Befehls zu Leerzeichen
(ibid.)

> Kann man jetzt in dieser for-Schleife die Leerzeichen irgendwie geschickt
> maskieren, so dass das Kommando als Einzeiler ausgeführt werden kann oder
> brauche ich die umständliche Variante mit Shell-Skript oder -Funktion?

Du brauchst ls(1) hier nicht, die Shell kann Dateinamen selbstständig
expandieren:

for i in *
do
du -hs "$i"
done

Jedoch kann auch du(1) einiges:

du -hs *

Die Shell expandiert den `*' zu den Namen der Dateien im aktuellen
Verzeichnis (je nach Shell-Optionen auch die versteckten) und übergibt du(1)
das Ergebnis. Dieser Ansatz führt nur dann zu Problemen, wenn die
Befehlszeile dadurch sehr lang wird (die Länge ist begrenzt).

Abhilfe schafft z. B. xargs(1), hier mit GNU find(1):

find . -maxdepth 1 -print0 | xargs -0r du -h

Die Summe müsstest Du dann aber selbst berechnen, z. B. mit awk(1).

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

unread,
Nov 17, 2012, 9:22:14 AM11/17/12
to
[X-Post & F'up2 de.comp.os.unix.shell]

Thomas 'PointedEars' Lahn wrote:

> Thomas Wildgruber wrote:
>> Ein Setzen der Umgebungsvariable in einem Einzeiler scheitert:
>>
>> ---snip---
>> $ IFS=$'\n' for i in `ls`; do du -hs "$i"; done
>> -bash: syntax error near unexpected token `do'
>> ---snap---
>
> `for' ist kein Befehl und hat daher kein eigenes Environment. Deshalb
> funktioniert das so nicht. Siehe Abschnitt SHELL GRAMMAR/Simple Commands
> in bash(1).

Stimmt immer noch.

> Dein Ansatz ist aber bereits fchsal. Command Substitution (`…` bzw. $(…)`
> konvertiert alle Whitespaces in der Ausgabe des Befehls zu Leerzeichen
> (ibid.)

Das ist jedoch Unfug; es werden nur Newlines am Ende der Ausgabe entfernt;
konvertiert zu Leerzeichen werden Newlines gern beim Word Splitting (wenn
IFS nicht gesetzt wurde). Aber fehlerträchtig ist der Ansatz trotzdem: Ein
Dateiname kann theoretisch Zeilenumbrüche enthalten. Mit `*' funktioniert
es hingegen immer[tm].
Message has been deleted

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2012, 5:06:13 AM11/18/12
to
Oliver Sch@d wrote:
^^^^^
Bitte reparieren.

> Übrigens gibt es auch auf der Shell lustige Sachen. Leg mal eine Datei
> "-rf" ab. Dann leg dort auch noch ein Verzeichnis an. Und dann mach im
> gleichen Verzeichnis ein "rm *". Die Datei "-rf" wirkt als Option für rm
> und löscht dann das Verzeichnis mit weg, was es ohne diese Option nicht
> getan hätte.
>
> Die Datei "-rf" wird aber auch nicht mitgelöscht, denn sie wird als
> Option erfasst.
>
> Beispiel:
>
> cd $(mktemp -d) # gehe in ein temporäres Verzeichnis
> mkdir bla1
> mkdir bla2
> rm * # gibt fehlermeldung
> touch -- "-rf" # Datei "-rf" anlegen
> rm * # tut, weil die Datei "-rf" als Option wirkt

Richtig. Abhilfe (wie bereits bei touch(1) gezeigt):

rm $OPTIONEN -- *


X-Post & F'up2 de.comp.os.unix.shell

Matthias Fulz

unread,
Nov 26, 2012, 9:37:39 AM11/26/12
to
On 2012-11-17, Thomas Wildgruber <excp...@web.de> wrote:
> Hi Group,
>
> um mir mal schnell einen Überblick über die Größen einiger Verzeichnisse
> anzeigen zu lassen, habe ich das 'du -hs' Kommando in einer for-Schleife
> laufen lassen aber bei Verzeichnissen mit Leerzeichen scheitert das
> Vorgehen und das maskieren der Leerzeichen mit Gänsefüsschen funktioert
> ein Nemwline-Ziechen (\n) setzen könnte aber das scheint nur in Skripts
> oder Shellfunktionen zu funktionieren:
>
> ---snip---
> $ foldersize ()
>> {
>> IFS=$'\n'
>> for i in `ls`; do
>> du -hs $i
>> done
>> }
> ---snap---
>
> Diese Funktion liefert dann die erwartete Ausgabe:
>
> ---snip---
> $ foldersize
> 9,3G DP4Lion.vmwarevm
> 2,0G Debian 5.vmwarevm
> 7,1G Debian 5_3.vmwarevm
> 5,6G Debian_6.0.0_GUI.vmwarevm
> 11G Debian_6_1.vmwarevm
> 14G MacOS_Lion_1.vmwarevm
> 32G W2K8R2_1.vmwarevm
> 25G Windows 7.vmwarevm
> 50G Windows XP Professional.vmwarevm
> ---snap---
>
> Jetzt habe ich aber das a) das Problem, dass zumindest in dieser Shell
> hinterher meine Umgebungsvariable IFS nicht mehr stimmt, was noch zu
> verschmerzen wäre (weil nur für diese Shell gültig) und b) ich es jetzt
> nicht hinbekommen habe das Setzen der Umgebungsvariable in meinem Quick and
> Dirty Einzeiler Workaround zu integrieren.
>
> Ein Setzen der Umgebungsvariable in einem Einzeiler scheitert:
>
> ---snip---
> $ IFS=$'\n' for i in `ls`; do du -hs "$i"; done
> -bash: syntax error near unexpected token `do'
> ---snap---
>
> Kann man jetzt in dieser for-Schleife die Leerzeichen irgendwie geschickt
> maskieren, so dass das Kommando als Einzeiler ausgeführt werden kann oder
> brauche ich die umständliche Variante mit Shell-Skript oder -Funktion?
>
> Thx & Bye Tom


Warum nicht einfach:

for i in *; do du -sh "${i}"; done

funktioniert bei mir problemlos.

Gruss,

Matthias


--
Wer A sagt, der muss nich B sagen, Er
kann auch erkennen, dass A falsch war.

---- GPG key: 1814DA35 ----

Torsten Berger

unread,
Nov 26, 2012, 3:08:29 PM11/26/12
to
Hallo Thomas,

On 2012-11-17, Thomas Wildgruber <excp...@web.de> wrote:

>> um mir mal schnell einen Überblick über die Größen einiger Verzeichnisse
>> anzeigen zu lassen, habe ich das 'du -hs' Kommando in einer for-Schleife

warum nicht so?

find . -maxdepth 1 -type d -exec du -hs {} \;


Viele Grüße

Torsten.


Helmut Hullen

unread,
Nov 26, 2012, 3:35:00 PM11/26/12
to
Hallo, Thomas,

Du meintest am 17.11.12:

> um mir mal schnell einen Überblick über die Größen einiger
> Verzeichnisse anzeigen zu lassen, habe ich das 'du -hs' Kommando in
> einer for-Schleife laufen lassen aber bei Verzeichnissen mit
> Leerzeichen scheitert das Vorgehen und das maskieren der Leerzeichen
> mit Gänsefüsschen funktioert nicht:

Schau Dir mal "ncdu" an - das erledigt solche Aufgaben wohl mit weniger
Aufwand.

Viele Gruesse
Helmut

"Ubuntu" - an African word, meaning "Slackware is too hard for me".

Thomas Wildgruber

unread,
Dec 1, 2012, 7:37:53 AM12/1/12
to
On 26 Nov 2012 21:35:00 +0100, Helmut Hullen wrote:

> Schau Dir mal "ncdu" an - das erledigt solche Aufgaben wohl mit weniger
> Aufwand.

In der Tat, ein interessanter Einwand. Obwohl ich auch schon das
du-Kommando komplizierter gestaltet habe als es sein müsste, scheint das
NCurces Disk Usage Utiliy brauchbar und ist sogar in den MacPorts zu
finden.

Ich schau mir das jetzt noch mal eine Zeitlang genauer an und entscheide
dann, ob es in Checkliste der Standardprogramme aufgenommen wird. Ich habe
als Supporter für etliche Workstations und Server (auch Kunden-Server)
nämlich häufig das Problem, dass ich ja nicht immer an meiner Maschine
sitze und somit häufig nur Zugang zu den Standardtools habe. Wenn ich meine
eigene Maschine zu sehr benutzerdefiniert aufrüste, habe ich manchmal schon
das Problem, dass ich an fremden Maschine wie der Ochs vorm Berg sitze,
weil mir plötzlich ein Tool abgeht. Deshalb bin ich immer darauf bedacht,
soweit wie möglich Standardtools zu verwenden...

In unixoiden Systemen ist zB der vi ein prominentes Beispiel. Wer den nicht
beherrscht, kann schnell in Probleme schlittern. Den vi hat nunmal jede
Maschine. Deshalb wird bei uns alles mit dem vi geschrieben und wenn das
dann sitzt, dann dürfen sie vim benutzen... ;-)

Bye Tom
--
"Ich weiß nicht, was der französische Staatspräsident Mitterand denkt, aber
ich denke dasselbe." (Helmut Kohl)
0 new messages