Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
k2
- Beiträge: 132
- Registriert: 14.08.2002 22:29:28
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von k2 » 17.04.2016 21:44:11
Hallo,
nachdem die Bash keine zweidimensionalen Arrays erlaubt, wollte ich als Workaround eindimensionale Arrays über ihren Namen referenzieren; leider klappt das nicht. Unten stehendes vereinfachtes Script sollte eigentlich das Array zahlen ausgeben - macht es aber nicht.
Code: Alles auswählen
#!/bin/bash
buchstaben=(a b c d e)
zahlen=(1 2 3 4 5)
array_auswahl='zahlen'
# nicht funktionierende Evaluierungen :-((
echo "ausgewähltes Array: "${${!array_auswahl}[*]}
Gibt es da einen Fehler bei der Evaluierung des Arraynamens? Ich finde ihn nicht. Oder kann man nur "normale" Variablen referenzieren? Wäre ziemlich brrr - dann müsste ich ein zweidimensionales Array zusammenklopfen...
Vielen Dank für Eure Mühen
k2
Zuletzt geändert von
k2 am 18.04.2016 19:09:34, insgesamt 1-mal geändert.
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 17.04.2016 21:57:09
Hallo k2,
ich selbst bin ein fauler Sack und mach deswegen vieles in Bash. Doch
ein für mich wesentlicher Punkt ist, zu lernen, ab welcher grösse man
keine Bash mehr verwenden sollte. Bash ist keine Programmiersprache
und und ab einer gewissen Grösse wird das programmieren in Bash
sehr schmerzhaft und krampfig.
Der Punkt scheint mir mit zweidimensionalen Arrays erreicht zu sein.
Falls Du auf Schmerzen stehst, kannst Du aber gerne mit eval weiter
machen. Damit bekommst Du garantiert ein 2dimensionales Array ge-
griffen.
Grüße,
h.
-
k2
- Beiträge: 132
- Registriert: 14.08.2002 22:29:28
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von k2 » 17.04.2016 22:10:19
Vielen Dank für die schnelle Antwort - aber kann man Arrays jetzt referenzieren? Gibt es einen Fehler in der Syntax oder kann man nur normale Variablen referenzieren?
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 17.04.2016 22:21:49
Beispiel eines assoziativen Arrays:
Code: Alles auswählen
# Wichtig! Die Variable muss als assoziatives Array deklariert werden, sonst sind nur numerische Indizies erlaubt
declare -A personen
# Beispieldaten zuweisen
personen[mueller_alter]=10
name=mueller
eigenschaft=alter
eval echo \$personen[${name}_${eigenschaft]
Nochmal als simples 2-dimensionales Array:
Code: Alles auswählen
declare -A matrix
matrix[0_9]=989
i=0
j=9
eval echo \${matrix[${i}_${j}]}
-
k2
- Beiträge: 132
- Registriert: 14.08.2002 22:29:28
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von k2 » 17.04.2016 22:44:41
Hi,
ich entnehme Deiner Antwort mal, dass man den Variablennamen eines eindimensionales Array nicht evaluieren kann so wie ich es vorhatte.
Ich werde dann wohl ein zweidimensionales Array nachbilden müssen ... jaaaa Schmerzen ...
Ein assoziatives Arrays nützt mir nichts, ich weiß an welcher Stelle was steht und kann das Array über einen numerischen Index bequem auslesen.
Aber ich muss Dir Recht geben:
Bash ist keine Programmiersprache und und ab einer gewissen Grösse wird das programmieren in Bash sehr schmerzhaft und krampfig.
mein Script ist derzeit bei 40k...
Vielen Dank für Deine Hilfe
-
uname
- Beiträge: 12398
- Registriert: 03.06.2008 09:33:02
Beitrag
von uname » 18.04.2016 08:19:55
Bash ist keine Programmiersprache und und ab einer gewissen Grösse wird das programmieren in Bash sehr schmerzhaft und krampfig.
mein Script ist derzeit bei 40k...
Ich habe mal in einen Ordner mit Perl-Scripten geschaut. Bei mehr als 100 Perl-Programmen liegt der Durchschnitt bei 5k bzw. bei weit unter 100 Zeilen.
-
MegaV0lt
- Beiträge: 173
- Registriert: 21.11.2011 11:16:07
- Lizenz eigener Beiträge: GNU General Public License
-
Kontaktdaten:
Beitrag
von MegaV0lt » 18.04.2016 08:28:44
Ein Beispiel aus meinem Backup-Skript
Das Array JOBS wurde mit daclare -A Jobs definiert.
Dort gespeichert sind die PIDs von rsync-Processen und die dazugehörigen Profilnamen. Beispiel:
"
echo ${JOBS[3295]}"
rsync_Prozess_1
Mit
${!JOBS[@]} werden die Namen der Indizes ausgegeben (3295, 3277, 3355, ...)
Schau Dir mal das hier an:
http://wiki.bash-hackers.org/syntax/arrays
Oder:
http://tldp.org/LDP/abs/html/arrays.html#ARRAYREF
"Das Internet? Gibt's diesen Blödsinn immer noch?"
[Homer Simpson], Sicherheitsinspektor im Kernkraftwerk Springfield.
-
k2
- Beiträge: 132
- Registriert: 14.08.2002 22:29:28
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von k2 » 18.04.2016 16:24:54
Danke für die Antwort, aber es scheint keine Möglichkeit zu geben, zwei indizierte Arrays über ihren _Namen_ zu referenzieren. Ich bastle einen Workaround...
Deine Links kenne ich, ich habe mich selbstverständlich ausführlich mit dem Problem der Referenzierung von Variablen und den Arrays auseinandergesetzt, bevor ich hier jemanden belästige (eval = "evil").
Gruß k2
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 20.04.2016 20:56:37
So, heute habe ich auch mal so etwas 2-dimensionales gebraucht. So habe ich das umgesetzt:
Code: Alles auswählen
#!/bin/bash
#
# Create CSV-Presentation Matrix of SQL-Data
# for importing into a spreadsheet application
#
# *** raw data from sql ***
#
# permission_name_1;perm_value;user_name_1
# permission_name_1;perm_value;user_name_2
# permission_name_1;perm_value;user_name_3
# ...
# permission_name_2;perm_value;user_name_1
# ...
# permission_name_MAX;perm_value;user_name_MAX
#
# *** output data ***
#
# ;user_name_1;...;user_name_max
# permission_name_1;perm_value_user_1;...;perm_value_user_MAX
# ...
# permission_name_MAX;perm_value_user_1;...;perm_value_user_MAX
#
SQL="
SELECT
permission.permission,
(SELECT 1 FROM account2permission
WHERE permission.id = account2permission.permissionid
AND account.id = account2permission.accountid),
account.comment
FROM account, permission;"
permission_name=""
permission_name_old=""
in_perm_record=0
perm_record=1
while read line ; do
IFS_OLD="$IFS"
IFS=";"
set $line
IFS="$IFS_OLD"
permission_name="$1"
(( in_perm_record = $in_perm_record + 1 ))
[ $in_perm_record -eq 1 ] && all_permission_names[$perm_record]=$permission_name
eval $permission_name[$in_perm_record]="$2"
if [ -n "$permission_name_old" -a "$permission_name" != "$permission_name_old" ]; then
in_perm_record=0
(( perm_record = $perm_record + 1 ))
fi
[ $perm_record -eq 1 ] && starface_users[$in_perm_record]="$3"
permission_name_old="$permission_name"
done < <( echo "$SQL" | psql -t --no-align -F \; asterisk )
# Write header with usernames first
for u in "${starface_users[@]}";do
echo -n \;$u
done
echo
for p in ${all_permission_names[@]};do
echo -n $p
for((user_index=0;$user_index < ${#starface_users[@]};user_index++));do
eval echo -n "\;\${$p[$user_index]}"
done
echo
done