ubuntuusers.de

Skript: Plus-Zeichen in String-Variable einfügen

Status: Gelöst | Ubuntu-Version: Kubuntu 14.04 (Trusty Tahr)
Antworten |

nielux

Anmeldungsdatum:
1. Januar 2009

Beiträge: Zähle...

Hallo zusammen,

ich versuche gerade das Zusammenführen von Dateien mit mkvmerge etwas zu automatisieren und habe daher ein kleines Skript gebastelt, das die passenden Dateien findet und dann an mkvmerge übergeben soll. Leider tritt dabei ein Problem auf. mkvmerge erwartet zwischen den einzelnen Dateien, die zusammengeführt werden sollen, ein Pluszeichen. Ich habe also versucht, die Dateien zu finden und zwischen die Dateinamen ein Plus-Zeichen einzufügen. Egal wie ich das Plus-Zeichen maskiert habe, sieht es aber im Ergebnis so aus, dass kein Plus-Zeichen im String erscheint; ich vermute das Zeichen wird als Konkatenationsoperator "verschluckt".

Hier auch mal noch mein Skript (eine Version davon zumindest 🙄):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
IFS=$'\n'
filename=""
i=0
for f in $(find . -iname "*.mkv" -type f | tac | sort); 
do
  if [ "$i" -le 1 ]
    then
      filename="$f"
      i=2
    else
      filename="$filename" + "\+" + "$f"
   fi
done;
echo $filename 
unset IFS

Ich habe auch schon versucht einfach nur die Dateinamen aneinander zu hängen und dann mit tr bei den Leerzeichen noch das Plus einzufügen... Leider hatte ich damit auch kein Erfolg, kann mir jemand weiter helfen?

Grüße nielux

PS: Nur der guten Praxis wegen, die Schleife mit der Abfrage ist, wie ich finde, nicht gerade elegant. Kann auch da jemand sagen, wie es besser ginge?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11243

Wohnort: München

nielux schrieb:

ich vermute das Zeichen wird als Konkatenationsoperator "verschluckt".

Sowas hat die Bash doch eigentlich gar nicht (man kann += zum Anhängen an einen String verwenden) - wenn man zwei Variablen mit einem "+" verbinden will, kann man das doch z.B. einfach so schreiben:

1
filename="${filename}+${f}"
$ a="Hallo"
$ b="Welt"
$ c="${a}+${b}"
$ echo $c
Hallo+Welt

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17599

Wohnort: Berlin

1
2
d=""; for f in ka*; do d=$d"$f+"; done ; echo $d
kars+kars.c+kars.cc+karscc+

nielux

(Themenstarter)

Anmeldungsdatum:
1. Januar 2009

Beiträge: Zähle...

Hm, das klappt in Deinem Beispiel, in meiner Schleife aber leider nicht. Wenn ich die Zeile, in der ich die Variablen zusammensetzen, durch Deine anleitung ersetze, also:

1
filename="${filename} + ${f}"

schreibe. Dann erhalte ich als Ausgabe von filename weiterhin alle Dateinamen, jeweils ein Name pro Zeile und weiterhin ohne das Plus. Woran liegt das denn?

nielux

(Themenstarter)

Anmeldungsdatum:
1. Januar 2009

Beiträge: 29

Habe jetzt mit dem zweiten Tipp experimentiert. Dabei wurde nur ein Plus zu viel gesetzt, um das wieder zu entfernen, bin ich bei

1
d=""; for f in *.mkv; do d=$d"$f + "; done ; echo ${d%% + };

gelandet. Danke für den Hinweis.

Allerdings ist mir nicht klar, warum es bei der ersten Lösung nicht gelingen will. Zur Erläuterung: Urspünglich wollte ich die Unterverzeichnisse in meine Dateisuche und die Bildung des Strings einbeziehen, daher hatte ich den find-Befehl integriert. Irgendwie scheint mir das auch das Problem zu sein. Kann da noch jemand etwas Licht ins Dunkel bringen?

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Was soll das in Zeile 11 in Deinem Skript eigentlich sein ??

Du "quotest" dort immer nur die einzelnen Variablen, aber nicht den Gesamtausdruck. Klar, dass die Shell dann irgendwas damit macht ...
Probier es doch mal einfach mit sauberem, einfachen "quoten":

      filename="$filename + $f"

Im Übrigen quotest Du auch sonst nicht sauber in Deinem Skript. Was meinst Du wohl, was passiert, wenn in einem Dateiname mal ein Newline ("\n") vorkommt ?! - da helfen nur Null-terminierte Strings, und die kann sort durchaus verarbeiten, wenn man es ihm sagt.

LG,

track

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17599

Wohnort: Berlin

1
2
3
4
5
6
for f in $(find . -iname "*.mkv" -type f | tac | sort)
do
   if [ "$i" -le 1 ];     then       filename="$f";       i=2
   else       filename="$filename+$f"
   fi 
done

Namensverkettung ist einfach d=$d$f - ohne Plus. Und Plus ist Plus.

1
d=$d+$f

Für Leerstellung und ähnlichen Klamauk in Dateinamen ist die Maskierung nötig. Das Plus ist automatisch nicht Teil des Variablennamens und muss daher nicht mit ${a}+$b oder $a"+"$b oder sonstwie maskiert werden.

Als Teil des Variablennamens funktioniert das Plus eh nicht - a+=b ist äquivalent mit a=a+b .

nielux

(Themenstarter)

Anmeldungsdatum:
1. Januar 2009

Beiträge: 29

Erst schon mal vielen Dank für die Erklärungen (insbesondere an user unknown)!

Also, wie ich zu Beginn geschrieben hatte, habe ich einiges probiert (bin eben kein Experte für die Shell). Da ich das Plus-Zeichen zunächst nicht hinbekommen habe, habe ich im Netz gesucht und dann vermutet, dass das Plus als ein Sonderzeichen gesehen wird und dann mit Backslash ausgegrenzt werden muss. Da das immer noch nicht geklappt hat, habe ich dann in Zeile 11 auch die gepostete Variante probiert.

Jetzt bin ich ja etwas schlauer, dennoch die Frage: Habt ihr noch einen Tipp zum Weiterlesen (insbesondere Verarbeitung von Zeichenketten)?

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17599

Wohnort: Berlin

nielux schrieb:

Jetzt bin ich ja etwas schlauer, dennoch die Frage: Habt ihr noch einen Tipp zum Weiterlesen (insbesondere Verarbeitung von Zeichenketten)?

Nein, aber als Tipp zu Zeichenketten in der Shell: Erwarte keine Ähnlichkeiten mit Sachen, die Du in anderen Sprachen gesehen hast.

Vieles klappt nicht, anderes wieder ist einfacher, v.a. gibt es keinen Typ "Zeichenkette". Vielleicht ist die Zeichenkette auch ein Dateiname oder ein Befehl und es passieren seltsame Sachen.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

nielux schrieb:

... Tipp zum Weiterlesen (insbesondere Verarbeitung von Zeichenketten)?

Vielleicht solltest Du mal in Greg's Wiki vorbei schauen, speziell bei Stringbearbeitung, Code vs. Variablen und Eval.

LG,

track

nielux

(Themenstarter)

Anmeldungsdatum:
1. Januar 2009

Beiträge: 29

Vielen Dank nochmal, habe noch das ein oder andere über den letzten Link entdeckt.

Zuerst war ich verunsichert, da einige Beispiele von dort nicht funktioniert haben. Dadurch habe ich aber auch noch gelernt, dass

1
sh skript.sh

das Skript über eine andere Shell aufruft und wenn ich die Bash haben möchte

1
./skript.sh

notwendig ist. Einiges erscheint mir jedenfalls sehr speziell; bin eben Java u.ä. gewohnt und so "low level" normalerweise nicht unterwegs. Greg erklärt jedenfalls gut.

Antworten |