Substitution

Command Substitution

Bei der Command substitution ersetzt der Output des ausgeführten Kommandos auf Standard-Output den Kommandonamen. Dabei werden alle new-line am Zeilenende gelöscht.


Es gibt 2 Formen:
`command`                    #alte Form
oder
$(command)                   # neue Form  bash, ksh

$(ls -l)					   # Directorylisting anzeigen
$(cat  /etc/fstab)           # Datei /etc/fstab anzeigen

Das Kommando $(cat file) kann durch die schnellere (builtin)
$(< file) ersetzt werden.
$(< /etc/fstab)              # Datei /etc/fstab anzeigen

  • Kommando-Substitutionen dürfen geschachtelt werden
  • Wenn die Substitution in Gänsefüßchen gesetzt wurde, erfolgt keine Expandierung von Pfadnamen
  • Kommando-Substitutions dürfen in beiden Formen geschachtelt werden. In der alten Form müssen aber die inneren `(backticks) maskiert werden. Die neue Form $(command) ist da wesentlich benutzerfreundlicher.


Parameter Substition

Bei der Substituierung werden Teile des Parameters ersetzt.
Eigentlich ist der : in der Syntax optional.
Ich hatte aber auch schon Probleme, das die bash ihn aber nicht haben wollte.

Besteht der Name des Parameter/Variablen aus mehreren Zeichen, so muss er in geschweifte Klammern eingeschlossen werden, wenn dahinter ein Buchstabe, eine Ziffer oder ein Underscrore folgt, das nicht Teil des Namens ist. Es ist sinnvoll in den Scripts immer {} zu verwenden.


Allgemeine Form       Beispiel
  ${parameter}         ${0}         	Scriptbezeichnung
			${1}         	Erster Übergabeparameter
			${feld}
  			          
  ${#parameter}       	${#*}        	Anzahl der übergebenen  Parameter
			${#@}         	dto
			${#feld}     	Länge der Valueangabe des  Parameters 
					(der Variable Feld)
			
			
  ${#parameter[*]}	  ${#array[*]} 	Anzahl der Elemente der  Tabelle array
  ${parameter:=word}       Defaultvalue zuweisen
  ${parameter:-word}       Defaultvalue benutzen
  ${parameter:+word}  	   Use alternate Value
  ${parameter:?word}       Display  Error  if  Null or Unset
  ${parameter:#pattern}    Remove small left pattern
  ${parameter:##pattern}   Remove large left pattern
  ${parameter:%pattern}    Remove small right pattern
  ${parameter:%%pattern}   Remove large right pattern
   
  ${parameter:offset}               Substring  Expansion
  ${parameter:offset:length}        Substring  Expansion
  

substitute Defaults


  ${parameter:=word}   	Defaultvalue zuweisen
           	Diese Form darf nicht auf positional  Parameter
			angewendet werden.
			Ist der Parameter nicht gesetzt oder seine  Länge ist
			Null, so wird der Parameter auf word gesetzt, an-
			schliessend wird substituiert.
    	print ${d:-$(date +%d.%m.%y)}
	10.01.94
	print  $d
	10.01.94
	

${parameter:-word} Defaultvalue benutzen Wenn der Parameter gesetzt ist und seine Länge ist nicht Null, so wird der Parameter substituiert, andernfalls word . Diese Form kann gut für die Vergabe von einem Default verwendet werden. vi ${1:-defdatei} Wurde eine Datei als Parameter 1 übergeben, so wird der vi damit aufgerufen, andernfalls wird defdatei verwendet. echo ${d:-$(pwd)}
${parameter:+word} Use alternate Value Ist der Parameter gesetzt und seine Länge ist nicht Null, so wird word substituiert. Andernfalls wird nichts substituiert


	set    a b c
	print  $3
	c
	
	print ${3:+alternate value}
	alternate value
	
	print $3
	c
	
	---------------------------------------
	#!/bin/bash
	verz=$(ls test)
	echo $*
	
	f2=${2}
	echo ${verz}
	
	# ersetze alte Parameter auf den alten Parameter $2 kann jetzt
	set test.sh  b c d e
	#auf den alten Parameter $2 kann jetzt nicht mehr zugegriffen werden
	echo $*
	
	echo $3
	# Ist der Parameter gesetzt und seine Länge  ist nicht Null,  so wird word substituiert.
	echo ${3+${f2}}
	
	
	detlef@i7-graf-st-dh:~/script_tests$ ./par_sub_1.sh bla blup blubber
	bla blup blubber
	files.txt leer.txt versuch.txt
	test.sh b c d e
	c
	blup
	detlef@i7-graf-st-dh:~/script_tests$
         

Error if Null or Unset

${parameter:?word} Wenn NULL oder unset Fehlermeldung ausgeben Ist der Parameter gesetzt und seine Länge ist nicht Null, so wird der Parameter substituiert. Andernfalls wird word ausgegeben und die Shell mit exit verlassen. Fehlt word, so wird eine Standardmeldung ausgegeben.

    unset a
    print ${x:?"Abbruch da Parameter fehlt"}
	bash:  x:   Abbruch da Parameter fehlt
	
	
	print ${a:?}
	bash:   a:  parameter null or unset
	

Remove Pattern

remove left pattern

${parameter:#pattern} Remove small left pattern Wenn das pattern mit dem Anfang des Inhalts von parameter übereinstimmt, so wird nur der Rest des Parameters substituiert, andernfalls wird der Inhalt des Parameters substituiert.
  geraet=/dev/ttyd01
  print  ${geraet:#/dev/}
  ttyd01
  
  
  
  
  
  
 $ pwd
 /usr/hahn/unix/ksh      Hier wir nur der relative Pfad ab dem
 $ echo ${PWD:#$HOME}    Homedirectory ausgegeben
 unix/ksh
 
 
 
 
 
 $ cd /usr2/user/unix0
 $ pwd
 /usr2/user/unix0
 $ echo ${PWD:#$HOME}    Hier wird der gesamte Pfad ausgegeben, da
 /usr2/user/unix0        der vordere Teil nicht mit $PWD übereinstimmt
 

remove large left pattern

${parameter:##pattern} remove large left pattern der größtmögliche passende vordere Teil soll entfernt werden. Hier wird i.d.R. mit Metazeichen gearbeitet
 $ pwd
 /usr/hahn/unix/ksh
 $ echo ${PWD:##*/}              Eignet sich gut, um den reinen Dateinamen
 ksh                             oder das letzte Verzeichnis zu isolieren.

remove right pattern

${parameter:%pattern} remove small right pattern Wenn das pattern mit dem Ende des Inhalts von parameter übereinstimmt, so wird der vordere Teil des Parameters substituiert. Mit anderen Worten, der übereinstimmende hintere Teil wird abgeschnitten.
geraet=/dev/ttyd01
print  ${geraet:%/ttyd01}
/dev


src_fln="./kto_1240_bank.txt"   # Eine .txt Datei  
fln=${src_fln%txt)pdf           # schneide .txt ab und hänge pdf dran
xdg-open ${fln}                 # öffne Die Datei mit dem 
                                # zugeordenet Programm



remove large right pattern ${parameter:%%pattern} remove large right pattern der größtmögliche passende hintere Teil soll entfernt werden Hier wird i.d.R. mit Metazeichen gearbeitet
$ x=usr/hahn/unix/ksh      	# Achtung kein / am Anfang
$ echo ${x:%%/*}           	#/gefolgt von beliebigen Zeichen
usr


Auschnitt aus Zeichenkette

Die Startposition einer Ausschnitts ${FOO:} (offset) zählt ab 0, d.h. ein positiver Wert von überspringt Zeichen vom Anfang. Aber darf auch *negativ* sein und man erhält dann die letzten Zeichen. Zu beachten ist aber, dass bei angaben Zahlen-Literalen zwischen dem ':' und dem '-' ein Leerzeichen stehen muss. Wenn hier eine Variable substituiert wird, kann das Leerzeichen entfallen ${FOO:$OFFSET}
 ${parameter:offset}                   Substring  Expansion





${parameter:offset:length}            Substring  Expansion
     Expandiert ab dem Offset zu der angegebenen Zeichenlänge
     oder bis zum Ende .
     length  und offset sind arithmetische Ausdrücke.
     Length muß; dabei zu einem Wert >= 0 expandieren.
     Wenn offset negativ ist, wird er vom Ende des Parameters
     verwendet.
      parameter is @, the result is length positional parameters 
      beginning at offset.
      If parameter is an array name indexed by @ or *, the result 
      is the length  members  of the  array  beginning  with 
      ${parameter[offset]}.
      Substring indexing is zero-based unless the positional
      parameters are used, in which case the indexing starts at  1.

Statt

    desk=${REPLY:${#REPLY}-1:1}

hätte man also auch

    desk=${REPLY: -1:1}

oder gleich

        desk=${REPLY: -1}

benutzten können. Da man logisch eh den ganzen Rest haben möchte, 
muss man nicht noch zusätzlich dessen Länge angeben. 
BTW: Auch der Längen-Parameter darf eine *negative* Zahl darstellen. 
Dann wird er nicht als Länge ab dem Start, sondern als abzuschneidene
Anzahl von Zeichen ab dem Ende interpretiert -- egal, wo der Start liegt.



${!prefix*} Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable.