michahe
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Hallo, meine script für eine Abfrage, die nur einen Datensatz liefert, ist OK:
| #!/bin/bash
strSQL="SELECT COUNT(\"ID\")
FROM \"Schema\".\"Tabelle\";"
Anzahl=$(psql -U "UserName" -d "DbName" --no-align --tuples-only --command="$strSQL")
echo "$Anzahl"
|
Jetzt möchte ich statt $Anzahl $Liste für mehrere Datensätze, funktioniert auch, aber leider ohne Zeilenumbruch pro Datensatz:
strSQL="SELECT \"ID\",\"Titel\", \"Name\", \"Vorname\"
FROM \"Schema\".\"Tabelle\";"
Liste=$(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --record-separator="\n" --command="$strSQL")
echo "$Liste"
Wie bekomme ich den Zeilentrenner?
|
TK87
Anmeldungsdatum: 8. Juli 2019
Beiträge: 227
Wohnort: Aachen
|
Moin, michahe schrieb: Wie bekomme ich den Zeilentrenner?
brauchst nur den record-separator ein wenig korrigieren:
| Liste=$(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --record-separator=$'\n' --command="$strSQL")
|
Alternativ könntest du natürlich auch ein Array verwenden:
| Liste=($(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --command="$strSQL"))
printf "%s\n" ${Liste[@]}
|
Gruß Thomas
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Danke!
TK87 schrieb:
... Alternativ könntest du natürlich auch ein Array verwenden:
| Liste=($(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --command="$strSQL"))
printf "%s\n" ${Liste[@]}
|
aber:
in der letzten Zeile erhalte ich Dateiende beim Suchen nach »"« erreicht.
|
TK87
Anmeldungsdatum: 8. Juli 2019
Beiträge: 227
Wohnort: Aachen
|
Dann hast du irgendwo in deinem Skript Quotes angefangen, die nicht beendet wurden. Das geht aus den beiden Zeilen nicht hervor. Folgendes funktioniert problemlos:
| #!/bin/bash
strSQL="SELECT ID,Vorname,Name FROM Schema.Tabelle;"
Liste=($(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --command="$strSQL"))
printf "%s\n" ${Liste[@]}
|
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Danke,
TK87 schrieb: Dann hast du irgendwo in deinem Skript Quotes angefangen, die nicht beendet wurden. ...}}}
Habe meinen Fehler gefunden, jetzt läuft es. Aber die Felder (und die Datensätze!) werden zeilenwese ausgegeben, zudem Felder mit Leerzeichen auch in einzelnen Zeilen. So wird aus einem Feld "Dr. med" die Ausgabe
Dr.
med.
Wie
bekomme ich eine Zeile je Datensatz? durchlaufe ich diese Zeilen zur Analyse? splitte ich die Zeilen am Feldtrenner '**', um etwas zu ändern?
|
TK87
Anmeldungsdatum: 8. Juli 2019
Beiträge: 227
Wohnort: Aachen
|
michahe schrieb: Aber die Felder (und die Datensätze!) werden zeilenwese ausgegeben
Die einzelnen Zellen der Tabelle? Kann eigentlich nicht sein, wenn du "**" als Trenner verwendest.
zudem Felder mit Leerzeichen auch in einzelnen Zeilen.
Das ist ganz normal. Standardmäßig trennt bash Werte immer bei Leerzeichen, Tabulatoren und Zeilenumbrüchen. Um das zu ändern und die Werte nur bei Zeilenumbrüchen zu trennen, musst du den Internal Field Separator auf "nur Zeilenumbrüche setzen", indem du folgendes in deinem Skript voransetzt (mache ich standardmäßig in jedem Skript):
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Hmm, Dein erster Vorschlag ohne Array war:
| strSQL="SELECT ID,Vorname,Name FROM Schema.Tabelle;"
Liste=$(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --record-separator=$'\n' --command="$strSQL")
|
und liefert zeilenweise:
1**Michaela**Müller
2**Dr. med. Peter**Bauer
Hier müsste ich noch den Zeilenumbruch erkennen und die Zeilen bei den '**' zerlegen, um die Elemente prüfen / bearbeiten zu können ...
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4439
Wohnort: Göttingen
|
Wenn Du mit den Daten wirklich arbeiten willst, nimm am besten etwas anderes als Bash. In Python/Perl oder den meisten höheren Programmiersprachen ist es vielleicht etwas aufwendiger, die erste Abfrage hinzubekommen, aber dann mit den Daten weiterzuarbeiten, ist erheblich angenehmer.
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Ich habe jetzt:
michahe schrieb: | strSQL="SELECT ID,Vorname,Name, PLZ, Ort FROM Schema.Tabelle;"
Liste=$(psql -U "UserName" -d "DbName" --no-align --tuples-only --field-separator="**" --record-separator=$'\n' --command="$strSQL")
|
und liefert zeilenweise:
1**Michaela**Müller**52072**Aachen
2**Dr. med. Peter**Bauer**10115**Berlin
Hier müsste ich noch den Zeilenumbruch erkennen und die Zeilen bei den '**' zerlegen, um die Elemente prüfen / bearbeiten zu können ...
Das klappt (fast) mit:
while read line; do #Mehrzeiligen Variableninhalt zeilenweise zerlegen; Quelle: https://stackoverflow.com/a/11902221
echo "LINE: '${line}'"
readarray -d "**" -t arrListe <<< $line # Zeile in Spalten zerlegen; Quelle: https://linuxsimply.com/bash-scripting-tutorial/string/split-string/
echo ${arrListe[0]}
echo ${arrFiles[1]}
echo ${arrListe[2]}
echo ${arrListe[3]}
echo ${arrListe[4]}
done <<< "$Liste"
Allerdings sind die Elemente [1] und [3] leer, [0], [2] und [4] liefern die richtigen Werte. Warum? @Doc_Symbiosis: Dein Vorschlag ist für mich nicht sinnvoll, da das hier die Ergänzung einer funktionierenden BASH-Anwendung wird ...
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4439
Wohnort: Göttingen
|
Hm, good guess: Funktioniert -d bei readarray vielleicht nur für ein Zeichen? EDIT: In der Tat nimmt -d anscheinend eine Menge von Zeichen als Wert, keinen String. Also setzt Du in deinem Fall effektiv '*' als Delimiter.
|
TK87
Anmeldungsdatum: 8. Juli 2019
Beiträge: 227
Wohnort: Aachen
|
na wenn du die Zeilen sowieso zerlegen willst und die einzelnen Werte prüfen willst:
1
2
3
4
5
6
7
8
9
10
11
12 | #!/bin/bash
IFS=$'\n'
strSQL="SELECT ID,Titel,Name,Vorname From Schema.Tabelle"
for LINE in $(psql -U "$USERNAME" -d "DbName" --no-align --tuples-only --field-separator=" **" --command="$strSQL");do
set -- $(sed 's#\*\*#\n#g' <<<$LINE) # <-- Setzt folgende Variablen:
# $1 = ID
# $2 = Titel
# $3 = Name
# $4 = Vorname
# Arbeite hier für die einzelnen Zeilen weiter
# ...
done
|
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Danke @TK87 schrieb: na wenn du die Zeilen sowieso zerlegen willst und die einzelnen Werte prüfen willst:
Von dieser Lösung verstehe ich gar nichts, deshalb würde ich gerne bei dieser Variante bleiben. Danke @Doc_Symbiosis schrieb: EDIT: In der Tat nimmt -d anscheinend eine Menge von Zeichen als Wert, keinen String. Also setzt Du in deinem Fall effektiv '*' als Delimiter.
Meinst Du den Delimter der SQL-Query ODER bei readarray -d "**"?
readarray -d "*" (mit einem STern liefert wie vor jedes zweite Element. '*' als Delimter in der SQL-Query ist nicht sinnvoll, da '*' als Teilstring der Feldinhalte vorkommen kann. Ggf. kann ich (wie?) ein nicht druckbares Steuerzeichen verwenden.
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4439
Wohnort: Göttingen
|
Ich meinte den Delimiter bei dem readarray. Die hier
readarray -d "**"
ist also genau das Gleiche wie dieses hier:
readarray -d "*" Kannst Du vielleicht mit Tab als Separator arbeiten oder kommt Tab auch als Zeichen in den Daten vor?
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 844
|
Danke!
Doc_Symbiosis schrieb: Kannst Du vielleicht mit Tab als Separator arbeiten
Ja, TAB wäre gut!. Aber definiere ich das in der SQL-Query ODER bei readarray -d?
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4439
Wohnort: Göttingen
|
Naja, Du musst den Delimiter ja bei beiden setzen. Also bei psql musst Du -F $'\t' setzen. Bei readarray musst Du dann -d $'\t' verwenden.
|