ubuntuusers.de

bash: Zusammenfügen von Strings

Status: Gelöst | Ubuntu-Version: Ubuntu 10.04 (Lucid Lynx)
Antworten |

stehjan

Anmeldungsdatum:
25. August 2010

Beiträge: 25

Hallo zusammen!

Ich, als bash-beginner, erstelle gerade ein Skript in dem es mir notwendig erscheint einen Verzeichnispfad aus mehreren String-Variablen zusammen zu setzen. Klingt an sich sehr einfach, führt aber dazu, dass zwischen dem ersten String und dem angehängten immer ein Leerzeichen entsteht:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#! /bin/bash

status=$(mktemp --tmpdir tmp.XXXXXXXXXX)

proj_dir=$HOME/Projekte       
echo $proj_dir                # Ausgabe: /home/stephan/Projekte


results="$(					
for f in $proj_dir/*/*.prj; do
    grep -m 1 -e '^[[:blank:]]*Proj' $f | cut -d = -f 2

[....]

	else
		echo "Neues Projekt anlegen"
		Proj_neu="$(yad --title="Neues Projekt" --width=500 ....
		
[...]

                echo $Proj_neu              # Ausgabe: Proj4 (ohne führende Leerstelle)
		echo $proj_dir/$Proj_neu    # Ausgabe: /home/stephan/Projekte/ Proj4

		PRO_DIR= "$proj_dir/$Proj_neu"  # Fehlermeldung: ./projselect.sh: Zeile 49: /home/stephan/Projekte/ Proj4 : Datei oder Verzeichnis nicht gefunden
                                                # bleibt aber nicht hängen
		echo $PRO_DIR
		mkdir "${proj_dir}"/"${Proj_neu}"    # Verzeichnis wird erstellt, der Verzeichnisname beginnt aber mit einer Leerstelle

[...]

Ich habe bereits alle möglichen Versionen der Klammer- oder Anführungszeichensetzung versucht, aber irgendwo beschwert er sich immer. Dabei stört mich die Fehlermeldung als solche weniger (solange es tut was es soll, aber schön ist anders). Aber ich würde es sehr begrüßen, wenn sich die führende Leerstelle vermeiden ließe. Zumal in der oberen Ausgabe von $proj_dir auch keine vorhanden ist.

Wenn jemand meinem Verständnis dieser Phänomene auf die Sprünge helfen könnte, wäre ich sehr dankbar.

Ich habe den kompletten Code zusätzlich als Anhang hochgeladen, vielleicht hilft's ja.

Gruß

Stephan

projselect.sh (1.7 KiB)
Download projselect.sh

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Mir fehlt Deine Datenstruktur, von daher kann ich das Skript nur sehr eingeschränkt testen. Aber mir fällt auf, dass Du sehr oft nicht "quotest" !

In Zeile 5 geht das ja noch (denn in "$HOME" kommt meistens kein Leerzeichen vor), aber spätestens in Zeile 11 müsste das "$f" doch "gequotet" werden, denn da gibt es ganz offensichtlich Leerzeichen im Namen ...

Überhaupt: diese Pipe mit grep und cut ist etwas unübersichtlich. Könnte man das nicht einfacher mit sed erreichen ?
(ich kapiere diese Geschichte jedenfalls nicht so richtig !)
Wie sehen die gesuchten Namen denn tatsächlich aus ? Gib bitte mal ein paar Beispiele.

Und dann könntest Du den Rückgabewert vielleicht besser in einer Variablen speichern statt in einer Datei. (vielleicht einfach mit || echo $? hinten dran ?) - Das würde auch noch einiges vereinfachen.

LG,

track

stehjan

(Themenstarter)

Anmeldungsdatum:
25. August 2010

Beiträge: 25

Hallo track,

Vielen Dank für Deine Tips.

|| echo $? funktioniert nicht, das Skript scheint irgendwo hängen zu bleiben ohne eine Fehlermeldung auszuspucken. An der Möglichkeit den Exitstatus des yad-Befehls an den Übergeordneten Prozess (Shell) zurückzugeben, hab ich ziemlich lange Try and Error betrieben, und mir scheint die Übergabe an eine Datei die beste und sicherste Lösung. Alternativ wäre vielleicht die Nutzung einer globalen Variablen möglich, aber wie gesagt ... Anfänger.

Diese unübersichtliche Pipe habe ich weitgehend aus einem yad-Beispielskript übernommen. Die grep-Zeilen machen nichts weiter als den Output für das yad-Skript aufzubereiten und sie funktionieren so wie ich es haben will. Ob man das mit sed besser machen könnte weiss ich absolut nicht, mit sed und den ganzen Regexp habe ich so meine Probleme (Was auf Dauer natürlich kein Zustand sein sollte). Und ich muss auch zugeben das mir die Funktion des $f hier völlig schleierhaft ist. Aber: never change a winning .... Du weißt schon.

Die gesuchten Dateieinträge sehen in etwa so aus:

1
2
3
Proj=Neu
Gen=24.8.2012
Akt=24.8.2012

wobei natürlich nur die letzten Spalten interessant sind. Ursprünglich war der cut-Befehl aus Zeile 22 auch noch an die Pipe angehängt aber das verträgt sich nicht mit der Statusabfrage.

Aber zurück zu dem eigentlichen Problem (aus dem Nirvana auftauchende Leerstelle):

Interessanterweise funktioniert es wenn ich eine entsprechende Befehlskette direkt in die Konsole eingebe:

1
2
3
4
[stephan@audiostudio ~]$ proj_dir=$HOME/Projekte
[stephan@audiostudio ~]$ Proj_neu=Proj7
[stephan@audiostudio ~]$ echo $proj_dir/$Proj_neu
/home/stephan/Projekte/Proj7

Hier keine plötzlich auftauchende Leerstelle(?!)

Aus dem Skript heraus scheint die überflüssige Leerstelle erst beim Zusammenfügen beider Strings zu entstehen. Wie bereits berichtet gibt echo $Proj_neu ebenfalls keine führende Leerstelle aus.

Ist mir alles immer noch ein Rätsel

Gruß

Stephan

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Aber da sind wir wieder baeim Thema "quoten" !

Die Variable "$f" enthält die Dateinamen aus der for- Schleife. Schon die solltest Du besser "quoten", falls doch mal ein Leerzeichen im Dateipfad vorkommt.

Wenn Du den Inhalt von "$Proj_neu" sehen willst, musst Du das natürlich auch "quoten", sonst schlürft die Shell bei der Ausgabe alle überschüssigen Leerzeichen weg:

echo "[$Proj_neu]"

Die [ und ] habe ich hier nur zur als graphische Verzierung eingefügt, damit man Leerzeichen vorne und hinten leichter sieht.

Im Zweifel solltest Du solche Probe- echos auch noch an anderen Stellen einbauen, damit Du einen Überblick bekommst.

LG,

track

stehjan

(Themenstarter)

Anmeldungsdatum:
25. August 2010

Beiträge: 25

Wow, tatsächlich: Mit Deiner echo-Version erscheint das Leerzeichen auch hier schon. Danke für die klare Erläuterung. Tatsächlich fällt jetzt auf, dass sowohl vor als auch hinter die Variable ein Leerzeichen gesetzt wird:

1
echo "[$Proj_neu]" --> [ ProjXX ]

# aber

1
proj_dir="[$HOME/Projekte]" --> [/home/stephan/Projekte]

Es scheint mir dass die Expansion (?) der Variablen durch das vorangestellte $-Zeichen zu der Leerstelle führt. Aber warum nicht im Fall des $HOME ??. Und vor allem, wie kann man das verhindern ??

Möglicherweise liege ich aber auch falsch.

Vielen Dank für weitere Aufklärung

Gruß

Stephan

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

stehjan schrieb:

Es scheint mir dass die Expansion (?) der Variablen durch das vorangestellte $-Zeichen zu der Leerstelle führt. Aber warum nicht im Fall des $HOME ??. Und vor allem, wie kann man das verhindern ??

Ne, die Leerzeichen kommen einfach von deinem Dialog, also von yad.

Dir würde

--separator=""

wohl mehr helfen als

--separator=" "

denn genau das erzeugt die Leerzeichen. Ob man das --item-separator=, braucht, wage ich auch zu bezweifeln.

(Frage aus Neugier: Hast du dir diesen yad-Aufruf von irgendwo rauskopiert? Vielleicht ist in deiner Quelle ja ein Fehler, den man korrigieren kann …)

stehjan

(Themenstarter)

Anmeldungsdatum:
25. August 2010

Beiträge: 25

Jaaaaa, genau, natürlich,

tatsächlich hast Du, Vain, natürlich recht. Die Leerstelle kann schon im Dialog eingefügt worden sein. Und siehe da, die Enfernung des --seperator-Eintrags wirkt sofort. Und, ja, Tatsächlich habe ich den yad-Aufruf rauskopiert. Und zwar aus dem Ubuntu-Wiki und ihn dann bis auf die Einträge welche ich vermeintlich brauchte zurückgestutzt. Dabei ist mir die Funktion des --seperator-Eintrags wohl nicht ganz klar gewesen. Nun, jetzt kenn ich sie.

Vielen Dank an alle Helfenden, ist ja fast schon peinlich auf diese einfache Lösung nicht selber gekommen zu sein.

Gruß

Stephan

Antworten |