Bash script Problem

easy.2ci

Commodore
Dabei seit
Mai 2006
Beiträge
4.387
Hey,

hat jemand eine schnelle Idee, wie ich folgendes in der bash umsetzen kann?

Ein Script muss einen Parameter akzeptieren, der immer eine Integer Zahl ist. z.B. 231 und aus dieser Zahl die Quersumme bilden.

In dem Fall also 2+3+1=6

Die Länge der Integerzahl kann variieren. Also script.sh 15 (also =6) oder script.sh 1321(also =7)



Ich weiß nicht wie ich die Integer Zahl in die einzelnen Faktoren zerlegen kann.
 

Zeroflow

Lt. Commander
Dabei seit
Juli 2006
Beiträge
1.971
am einfachsten mit modulo in ner schleife

z.B bei x = 123 kriegst du mit

i = x mod 10 //i = 3
x = x / 10 // x=12

das hald in ne schleife und gut is

EDIT: den rest solltest du eh selbst schaffen ;) ein wenig herausforderung soll ja noch bleiben ^^
 
Zuletzt bearbeitet:

Coolinger

Lt. Junior Grade
Dabei seit
März 2001
Beiträge
316
Hi,

ich würds, so auf die schnelle, so machen:

eval echo '$(('$(echo $1 | sed -e 's/\(.\)/\1\ +\ /g') 0'))'

dadurch wird die Zeichenkette $1 durch sed so ersetzt, dass nach jedem einzelnem Zeichen ein + eingefügt wird. Da dadurch zum Schluss ein + übrigbleben würde, wird hinten dran nochmal ne Null gehängt.

Das ganze wird mit dem echo noch um $(( vorne und )) hinten erweitert, was die bash zum berechnen veranlasst.
Dieser sting wird dann per eval ausgeführt.

Da ist jetzt natürlich keine Abrage dabei, ob das Argument $1 wirklich nur aus Ziffern besteht, aber als quick'n'dirty sollte es durchgehen.

Bin schon mal auf weitere Lösungen gespannt, evtl. bringt sogar jemand das sed weg :)
 

bu1137

Captain
Dabei seit
Apr. 2010
Beiträge
3.249
Code:
#!/bin/bash
x=${1//[^0-9]/}
sum=0
for ((i = 0; i < ${#x}; i++)); do
    ((sum += ${x:i:1}))
done
echo $sum
 
Zuletzt bearbeitet:

easy.2ci

Commodore
Ersteller dieses Themas
Dabei seit
Mai 2006
Beiträge
4.387
Besten Dank für Eure beiden Lösungen. Das Script von bu1137 kann ich nachvollziehen. Sieht prima aus.

Die Lösung von Coolinger sieht extrem geil aus, der Einzeiler hat definitiv was ^^ Ich komm allerdings mit dem regulären Ausdrücken noch nicht klar, versuche aber derzeit noch das ganze auseinander zu nehmen. Würds gern bis ins letzte Detail verstehen.

Wälz gerade dazu die sed Doku durch ;-) ...und wollte nur noch schnell Rückmeldung geben


Vielen Dank
Ergänzung ()

bin bei der sed Sache nun soweit:

Im Kern dreht sich die Zeile von Coolinger um folgenden Befehl:

Eingabe: echo 123 | sed 's/\(.\)/\1\ +\ /g'
Ausgabe: 1 + 2 + 3 +

Das mit der 0 die noch fehlt und das eval sind soweit klar.

Schwierigkeiten macht mir noch der sed. Ich versteh das so:
sed 's/\(.\)/\1\ +\ /g'

Das s heisst, ersetze den roten Teil durch den grünen Teil. Das /g am Ende heisst das der Vorgang mehrfach innerhalb einer Zeile ausgeführt wird.

Bleiben also noch die beiden farbigen regulären Ausdrücke über. Und da steig ich nicht hinter.
Kann jemand bestätigen dass ich derzeit auf dem richtigen Weg bin?
 
Zuletzt bearbeitet:

bu1137

Captain
Dabei seit
Apr. 2010
Beiträge
3.249
Ja, das siehst du soweit richtig. Die Ausdrücke:

Suchen nach: \(.\) -> Der Punkt '.' steht für jedes Zeichen, egal was. Die \ brauchts zum escapen, und die () um in der Ersetzung auf das Zeichen zurückgreifen zu können (backreference)

Ersetzen: \1\ +\ -> \1 ist wie gesagt, backreference, nimmt das per (.) selektierte zeichen und setzt es hier wieder ein. \ wieder zum escapen von den leerzeichen (wobei unnötig), der rest sollte klar sein.

Bleibt anzumerken: Schneller ist's per sed eher nicht.

Damit's nicht ganz so hässlich ist (die ganzen / und \) kannst bei gnu sed übrigens auch so machen (-r damit () nicht escaped werden muss, und anstatt / kannst du so oder so benutzten was du willst, ich hab einfach mal @ genommen:

sed -r "s@(.)@\1 + @g"
 
Zuletzt bearbeitet:
Top