kutteldaddeldu
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Ich bin gerade dabei, mir mit Hilfe von Yad eine kleine graphische Eingabemaske für einen Taskwarrior-Eintrag zu bauen. Nach Beendigung der Eingabe soll folgender Befehl ausgeführt werden: task add "AUFGABE" project:"PROJECT" +WO [oder +HO] +TAG1 +TAG2 +TAG3 due:DUE Ein Beispiel könnte also so aussehen: task add "Fenster putzen" project:"Wohnungsputz vor Herbstanfang" +HO +nervig +dringend +Spülmittel due:22.9.19 Tags müssen bei Taskwarrior mit einem vorangestellten Pluszeichen eingegeben werden (also z.B. „+Computer“). Das Problem ist, dass es mehrere Tags geben kann – aber nicht grundsätzlich klar ist, wie viele genau, da sich ihre Anzahl je nach neu einzugebender Aufgabe unterscheidet. (Der einzige Tag, der auf jeden Fall vorkommen muss, ist entweder +HO oder +WO – also „home“ oder „work“.) Alle anderen Felder haben genau einen Wert (jede Aufgabe wird also auch nur einem Projekt zugeordnet). Ich habe mir jetzt folgendes Yad-basierte Script zusammengeschustert (für genau fünf einzugebende Tags – deren Zahl soll aber beliebig sein, siehe unten): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | TASK=$(echo "WO,HO")
YADAUSGABE=$(yad --center --width=800 --height=80 --title="Neue Aufgabe" --form --date-format="%-d.%-m.%y" --form --item-separator="," \
--field="Aufgabe:" --field="Fälligkeit:":DT --field="Arbeit (WO) oder Freizeit (HO)?":CBE --field="Tags (kommagetrennt):" --field="Projekt:" "" "" "$TASK" "")
AUFGABE=$(echo "$YADAUSGABE" | cut -d'|' -f1)
DUE=$(echo "$YADAUSGABE" | cut -d'|' -f2)
TASKWHERE=$(echo "$YADAUSGABE" | cut -d'|' -f3)
TAGS=$(echo "$YADAUSGABE" | cut -d'|' -f4)
PROJECT=$(echo "$YADAUSGABE" | cut -d'|' -f5)
TAG1=$(echo "$TAGS" | cut -d',' -f1)
TAG2=$(echo "$TAGS" | cut -d',' -f2)
TAG3=$(echo "$TAGS" | cut -d',' -f3)
TAG4=$(echo "$TAGS" | cut -d',' -f4)
TAG5=$(echo "$TAGS" | cut -d',' -f5)
task add \""$AUFGABE"\" project:\""$PROJECT"\" +"$TASKWHERE" +"$TAG1" +"$TAG2" +"$TAG3" +"$TAG4" +"$TAG5" due:"$DUE"
|
Das scheint soweit okay zu sein. Allerdings habe ich ein Problem mit den Tags: Ich will nicht, dass ein leeres Pluszeichen (oder mehrere) im Befehl erscheint, wenn es (wie hier im Beispiel) weniger als fünf (oder eine andere Anzahl von) Tags gibt. (Grundsätzlich soll es eine beliebige Anzahl – von Null bis sehr viele – von Tags geben können.) Was ich also machen müsste, wäre etwas wie das Folgende: Zähle die kommagetrennten Werte in der Variable TAGS. Erzeuge genauso viele neue Variablen „TAG#“, wie diese Zählung ergeben hat. Füge im abschließenden Befehl „task add“ genauso so viele Werte „+TAG#“ ein, wie als Variablen „TAG#“ erzeugt wurden.
Hier versagen meine kümmerlichen Shell-Scripting-Kenntnisse vollkommen. Ich vermute, man kann das Problem irgendwie mit case angehen – aber wie? Hat jemand Lösungsansätze?
|
NORACSA
Anmeldungsdatum: 31. Januar 2010
Beiträge: 180
|
Variable Variablennamen spricht man wie folgt an: https://stackoverflow.com/a/10820494/6552776
|
kutteldaddeldu
(Themenstarter)
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Danke! Ich muss mich nachher (jetzt komme ich nicht dazu) da mal ein bisschen einlesen und das ausprobieren. Zwei Fragen allerdings vorweg: Kann man mit dieser Lösung auch den Fall abdecken, dass es (neben „+HO“ oder „+WO“) keine zusätzlichen Tags gibt, dass also i = 0 ist? Wenn ich das richtig sehe, betrifft dieser Ansatz nur mein oben unter Punkt „2.“ aufgeführtes Problem, nicht aber das unter „3.“ genannte?
Zusätzliche Frage: das Zählen der kommagetrennten Werte in „TAGS“ erfolgt wohl am besten mit awk?
|
kutteldaddeldu
(Themenstarter)
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Hmmm. Ich habe jetzt etwa rumprobiert, aber nicht wirklich verstanden, wie mir die „Variable Indirection“ (die ich generell nur halb verstehe) in meinem Fall helfen kann. Ein anderer Versuch war der folgende: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | TASK=$(echo "WO,HO")
YADOUTPUT=$(yad --center --width=800 --height=80 \
--title="Neue Aufgabe" \
--form --date-format="%-d.%-m.%y" --form --item-separator="," \
--field="Aufgabe:" \
--field="Fälligkeit:":DT \
--field="Arbeit (WO) oder Freizeit (HO)?":CBE \
--field="Tags (kommagetrennt):" \
--field="Projekt:" "" "" "$TASK" "")
TASK=$(echo "$YADOUTPUT" | cut -d'|' -f1)
DUE=$(echo "$YADOUTPUT" | cut -d'|' -f2)
TASKWHERE=$(echo "$YADOUTPUT" | cut -d'|' -f3)
TAGS=$(echo "$YADOUTPUT" | cut -d'|' -f4)
PROJECT=$(echo "$YADOUTPUT" | cut -d'|' -f5)
TAGCOUNT=$(echo "$TAGS" | awk -F, '{print NF}')
for (( i = 1; i <= $TAGCOUNT; i++ ))
do
TAG"$i" = $(echo "$TAGS" | cut -d',' -f"$i")
done
for (( i = 1; i <= $TAGCOUNT; i++ ))
do
TAGX"$i" = +"$TAG""$i"
done
echo \""$TASK"\" project:\""$PROJECT"\" +"$TASKWHERE" „$TAGX-Werte-Schleife“ due:"$DUE"
|
Hier habe ich jetzt zwei Probleme, die beiden for-Schleifen und die „$TAGX-Werte-Schleife“: Die for-Schlaufen funktionieren nicht (auch nicht mit anderen Quotes). Es wird immer nur der erste Tag gebildet. Zudem kommt für alle gewünschten Variablen eine Ausgabe à la command not found: TAG2 (Die von mir als Variablen gewünschten "TAG#" werden also als Befehle interpretiert. Die Fehlermeldung kommt allerdings schon bei TAG1, das aber tatsächlich als Variable gebildet und – auch als TAGX1 – ausgegeben wird.) Die Grundidee war, in der ersten for-Schlaufe zunächst Variablen TAG# zu bilden, die jeweils den kommaseparierten Tag-Variablen entsprechen, die in Yad eingegeben wurden. Dann werden in der zweiten for-Schlaufe Variablen TAGX# gebildet, die TAG# entsprechen, deren Werte aber jeweils noch ein „+“-Zeichen (das ich für Taskwarrior brauche) vorangestellt haben. Das funktioniert aber nicht. Für die Ausgabe könnte dann eine „$TAGX-Werte-Schleife“ erfolgen. Diese könnte etwa so funktionieren: Wenn es eine Variable TAGX# gibt, dann soll diese hier angegeben werden. Wenn TAGX1 zum Beispiel „+dringend“ lautet, soll das entsprechend ausgegeben werden. Wenn es eine weitere besetzte Variable gibt (zum Beispiel TAGX3), soll diese (im Beispiel per echo, später im task add-Befehl) ausgegeben werden. Das soll so lange gehen, bis es keine Werte mehr gibt. Ab dann soll nichts mehr ausgegeben werden (auch kein Leerzeichen).
Auch hier habe ich keine Ahnung, wie das geht.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11181
Wohnort: München
|
Ich würde das mit Arrays machen (und durch setzen des IFS auf die jeweils interessanten Trennzeichen kann man sich das Parsen der Ausgabe von yad erleichtern):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #!/bin/bash
TASK=$(echo "WO,HO")
YADOUTPUT=$(yad --center --width=800 --height=80 \
--title="Neue Aufgabe" \
--form --date-format="%-d.%-m.%y" --form --item-separator="," \
--field="Aufgabe:" \
--field="Fälligkeit:":DT \
--field="Arbeit (WO) oder Freizeit (HO)?":CBE \
--field="Tags (kommagetrennt):" \
--field="Projekt:" "" "" "$TASK" "")
IFS='|' read -r task due where taglist project <<< "$YADOUTPUT"
IFS=',' tags=($(printf '+%s,' $taglist))
echo \""${task}"\" project:\""${project}"\" +"${where}" "${tags[@]}" due:"${due}"
|
|
kutteldaddeldu
(Themenstarter)
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
|
kutteldaddeldu
(Themenstarter)
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Ich habe leider doch noch zwei kleine Probleme entdeckt, von denen ich nicht weiß, wie ich sie lösen kann: Bei der Ausgabe des Projekts (also der letzten einzugebenden Variable) wird nach dem Projektnamen noch die Pipe (die Yad als Trennzeichen benutzt) angegeben. Bei der Ausgabe der Tags wird nur dem ersten Tag ein „+“-Zeichen vorangestellt.
Ich habe versucht, das zweite Problem zu lösen, indem ich vor "${tags[@]}" ein Pluszeichen gestellt habe, das hilft aber nicht.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11181
Wohnort: München
|
Hast du da eventuell noch irgendetwas am Quoting oder andere Dinge geändert?
Bei mir sieht das unter Ubuntu 19.04 so aus, wenn ich das Skript mit einem eingefügtem set -x in der zweiten Zeile laufen lassen:
1
2
3
4
5
6
7
8
9
10
11
12 | $ bash test.sh
++ echo WO,HO
+ TASK=WO,HO
++ yad --center --width=800 --height=80 '--title=Neue Aufgabe' --form --date-format=%-d.%-m.%y --form --item-separator=, --field=Aufgabe: --field=Fälligkeit::DT '--field=Arbeit (WO) oder Freizeit (HO)?:CBE' '--field=Tags (kommagetrennt):' --field=Projekt: '' '' WO,HO ''
+ YADOUTPUT='In der Nase bohren|28.9.19|HO|Nase,Gesicht,Popel,Gesichtserker|Langeweile|'
+ IFS='|'
+ read -r task due where taglist project
+ IFS=,
+ tags=($(printf '+%s,' $taglist))
++ printf +%s, Nase Gesicht Popel Gesichtserker
+ echo '"In der Nase bohren"' 'project:"Langeweile"' +HO +Nase +Gesicht +Popel +Gesichtserker due:28.9.19
"In der Nase bohren" project:"Langeweile" +HO +Nase +Gesicht +Popel +Gesichtserker due:28.9.19
|
Zeile 12 ist die resultierende Ausgabe des echo-Befehls.
|
kutteldaddeldu
(Themenstarter)
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Hallo seahawk1986, herzlichen Dank für deine Mühen! Wenn ich es richtig sehe, funktioniert jetzt alles. (Der Fehler, den ich vorher beschrieben habe, lag wohl daran, dass ich deine Befehle im Terminal ausgeführt habe und nicht das Bash-Script gestartet habe. Bitte entschuldige die unnütze Mehrarbeit!) Ich habe in deinem Script zum Auslesen der Projektnamen doch noch die Anführungszeichen um die Namen entfernt – das sah in der Eingabemaske etwas komisch aus. Im eigentlichen Yad-Script habe ich zudem eine Auswahlbox (auch) für die bestehenden Projekte eingefügt. Für die Nachwelt: Das sind jetzt die beiden Scripts. Yad muss natürlich installiert sein, ebenso python-taskw. seahawk1986s Script python-tw-projects.py liegt bei mir im PATH. taskwarrior-yad-input.sh (das eigentliche Script): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | #!/bin/bash
PROJECTS=$(python-tw-projects.py)
TASK=$(echo "WO,HO")
YADOUTPUT=$(yad --center --width=800 --height=80 \
--title="Neue Aufgabe" \
--form --date-format="%-d.%-m.%y" --form --item-separator="," \
--field="Aufgabe:" \
--field="Fälligkeit:":DT \
--field="Arbeit (WO) oder Freizeit (HO)?":CB \
--field="Tags (kommagetrennt):" \
--field="Projekt:":CBE \
"" "" "$TASK" "" "$PROJECTS")
IFS='|' read -r task due where taglist project <<< "$YADOUTPUT"
IFS=',' tags=($(printf '+%s,' $taglist))
if [ -z "${task}" ]; then
exit 2;
fi
task add \""${task}"\" project:\""${project}"\" +"${where}" "${tags[@]}" due:"${due}"
|
Das Script python-tw-projects.py zum Auslesen der Projektnamen, das ebenfalls vorhanden sein muss: 1
2
3
4
5
6
7
8
9
10
11
12 | #!/usr/bin/env python3
from taskw import TaskWarrior
w = TaskWarrior()
tasks = w.load_tasks()
project_names = set()
for state, task_items in tasks.items():
for t in task_items:
project_names.add(t.get('project'))
print(",".join(f'{item}' for item in sorted(filter(None, project_names))))
|
Edit: Ich habe noch einen Befehl eingefügt, der die Ausführung des Scripts unterbricht (also keine „task add“-Operation durchführt), sollte das mit „Aufgabe:“ abgefragte Feld leer sein.
|