# Bash Stringmanipulation

## musv

In Anlehnung zu [https://forums.gentoo.org/viewtopic-t-568779.html]sed[/url] würde ich gern mal einen Thread zur reinen Stringmanipulation unter Bash eröffnen, da ich in letzter Zeit häufiger damit zu tun hab. Ein paar Links dazu:

http://mywiki.wooledge.org/BashFAQ/100#How_do_I_do_string_manipulations_in_bash.3F

Dazu steh ich momentan vor dem konkreten Problem, dass ich gern das Auftreten mehrerer gleicher Zeichen auf eins reduzieren würde. Also: 

meine,liste,,mit,,,komma soll werden zu: meine,liste,mit,komma. 

Dummerweise scheint der +-Operator nicht zu funktionieren. * und ? klappen ohne Probleme:

```
#!/bin/bash

a="meine,liste,,mit,,,komma"

echo ${a//,+/,}

echo ${a//,{2,}/,}
```

Wie kriegt man das mit reiner Bash hin?

Und als nächstes such ich noch 'ne Möglichkeit, alle Umlaute in einem String zu ersetzen. Also: äöü -> ae oe ue

----------

## fuchur

Hi

 *musv wrote:*   

> 
> 
> Und als nächstes such ich noch 'ne Möglichkeit, alle Umlaute in einem String zu ersetzen. Also: äöü -> ae oe ue

 

Hier glaube ich kann ich weiterhelfen das andere verstehe ich nicht so ganz.

```
echo äüö | iconv -t ASCII//TRANSLIT
```

MfG

----------

## l3u

Muss es rein Bash sein? Kein Pipen irgendwohin? Mit was anderem wär's leichter …

----------

## musv

Ich wollte mal ohne sed, awk & Co. auskommen. Mit bash hat man erstaunlich viele Möglichkeiten bei der Stringmanipulation, die häufig auch noch kürzer sind als mit sed. 

Ich hab's jetzt erst mal mit relativ dummer Logik abgedeckt:

```
var=${var//,,/,}
```

Bisher hatte ich keinen Anwendungsfall, bei dem mehr als 2 Kommata aufgetreten sind. Verlockender wäre natürlich eine eher generische Lösung gewesen. 

Ok, iconv war dann doch zu bequem. Vor allem, weil es vermutlich auch andere Sprachen abdeckt.

----------

## mv

 *musv wrote:*   

> Mit bash hat man erstaunlich viele Möglichkeiten

 

Sehr eingeschränkt. Wenn es schon nicht-POSIX und shell-ähnlich sein soll, würde ich zsh nehmen, die wenigstens Patterns hat, die an reguläre Ausdrücke heranreichen (und teilweise sogar mächtiger sind):

```
${var//,##/,}
```

Andererseits: Wenn man sowie nicht-POSIX benutzt, wieso dann nicht gleich eine Hochsprache wie Perl?

```
s/,*/,/g
```

----------

## musv

Die Antwort ist relativ einfach. Bei mir auf Arbeit ist auf jedem Rechner Bash installiert, da es einfach die Standardshell der Enterprise-Distributionen ist. ZSH könnte auch installiert sein. Ist aber eine optionale Zugabe. 

Perl ist so 'ne Sache. Ich hab mich da mal in 3 Tagen etwas eingearbeitet. Wenn man es täglich benutzt, kann man da richtig schöne Sachen mit bauen. Bei der Wahl der Hochsprachen bin ich dann aber eher bei Python gelandet. 

Der konkrete Anwendungszweck für das Script war die Filterung einer LDAP-Abfrage. So im Nachhinein fand ich da Bash die beste Wahl. Der Schreibaufwand war angemessen und wäre mit anderen Sprachen auch nicht kürzer gewesen. Und irgendwie muss ich auch zugeben, dass mir die Stringmanipulationssyntax der Bash durchaus gefällt.

----------

## mv

 *musv wrote:*   

> Perl ist so 'ne Sache.

 

Bei einer Problemstellung, die geradezu nach regulären Ausdrücken schreit, ist es halt die natürliche Wahl.

 *Quote:*   

> Ich hab mich da mal in 3 Tagen etwas eingearbeitet.

 

Huch, so lange!? Einfach den Code tippen, der einem von irgendeiner Sprache in den Sinn kommt, und schon funktioniert es  :Wink: 

Wenn man bestehenden Code lesen muss, ist es natürlich etwas anders, vor allem, wenn nicht von einem Profi geschrieben…

 *Quote:*   

> Bei der Wahl der Hochsprachen bin ich dann aber eher bei Python gelandet.

 

Python ist nicht schlecht, aber m.E. zu umständlich. Wenn man sich z.B. anschaut, für welchen Pipifax man in portage seitenweise Code braucht, um irgendwelche trivialen I/O-Exceptions zu behandeln… Wenn das Programm so komplex wird, dass Objektorientierung auf dem Python-Level sinnvoll ist, würde ich zu C++ greifen: Mit boost ist das mindestens genauso bequem wie python, hat aber die ganzen Vorteile, die die statische Typprüfung beim Kompilieren mit sich bringt. Aber für ein einfaches Skripting-Problem, erscheint mir weder C++ noch Python angemessen.

 *Quote:*   

> Und irgendwie muss ich auch zugeben, dass mir die Stringmanipulationssyntax der Bash durchaus gefällt.

 

Ja, manchmal schreibe ich Skripte auch in Shell. Aber meistens bereue ich es hinterher, weil ich dann irgendwann doch etwas einbauen will, was mit Shell nicht oder nur sehr umständlich geht, und was mit Perl eine Zeile wäre. Außerdem hat man in Perl keine Inkompatibilitätsprobleme; man kann damit Code sauber so schreiben, dass er sogar mit Windows/Apple läuft (mit den komplizierteren Strukturen wie laufwerk:\foo\bar bzw. Extrawürsten für Dateien/Directories).

----------

## Yamakuzure

 *musv wrote:*   

> 
> 
> ```
> #!/bin/bash
> 
> ...

 Mit einem kleinen Umweg über ein Array:

```
 $ a="meine,liste,,mit,,,komma" ; b=( ${a//,/ } ) ; a="${b[@]}" ; echo "${a// /,}"

meine,liste,mit,komma
```

Bash unterstützt zwar reguläre Ausdrücke, aber leider nur als Testelement zwischen [[ und ]].

----------

## Yamakuzure

 *mv wrote:*   

> Ja, manchmal schreibe ich Skripte auch in Shell. Aber meistens bereue ich es hinterher, weil ich dann irgendwann doch etwas einbauen will, was mit Shell nicht oder nur sehr umständlich geht, und was mit Perl eine Zeile wäre.

 Das kommt mir irgendwie bekannt vor.   :Rolling Eyes: 

Ich weiß gar nicht, wie oft ich schon ein kleines "Mal-eben-nebenbei"-Skript weggeworfen, und durch ein Perl-Programm ersetzt habe.   :Laughing: 

----------

