Kann mir jemand die Option -C von mapfile genauer erklären?
Die Built-in-Funktion mapfile (bzw. readarray) ist eine praktische Sache, z. B. lassen sich so über eine while-read-Schleife gut gleichförmige Werte in einer csv-Datei nutzen. Bei der Erkundung der verschiedenen Möglichkeiten bin ich jedoch bei der Option -C hängen geblieben.
Soweit ich das anhand von manpage und diversen Anleitungen herausfinden konnte, kann man mit der Option -c (Kleinbuchstabe) eine bestimmte Anzahl von Indizes einlesen, nach denen mit Hilfe der Option -C (Großbuchstabe) etwas eingefügt werden kann, das sich »Callback« nennt. Leider wurde mir jedoch nicht klar, was genau man mit diesem Callback bewirken kann. Anschauliche Beispiele dazu gibt es im Internet leider keine.
Kann mir jemand ein paar praktische Anwendungsfälle zeigen?
1 Antwort
Ein Callback ist einfach eine Funktion, die automatisch aufgerufen wird, wenn ein bestimmtes Ereignis eintritt – in diesem Fall jedes Mal, wenn "mapfile" eine neue Zeile liest.
Der Callback von mapfile ermöglicht es dir so, für jede Zeile, die eingelesen wird, eine Funktion (der Callback) aufzurufen. Diese Funktion kannst du verwenden, um die Zeilen zu bearbeiten oder eine andere Art der Verarbeitung durchzuführen.
Nehmen wir mal ein kleines Beispiel
callback() {
echo "${1//,/ }"
}
mapfile -C callback ABC.csv
Was passiert hier?
- Jede Zeile der CSV-Datei wird eingelesen.
- Die Callback-Funktion wird aufgerufen und ersetzt die Kommas durch Leerzeichen.
- Die veränderte Zeile wird ausgegeben
Leider zu früh gefreut:
$ cat nachstellen.sh
#!/bin/bash
callback() {
echo "${1//,/ }"
}
mapfile -C callback ABC.csv
$
$ cat ABC.csv
Name,Vorname,Alter
Meier,Sven,33
Müller,Volker,47
Schulze,Frieder,63
$
$ source nachstellen.sh
bash: mapfile: »ABC.csv«: Ist kein gültiger Bezeichner.
$
Dann habe ich das Skript ein wenig modifiziert:
$ cat nachstellen.sh
#!/bin/bash
callback() {
echo "${1//,/ }"
}
mapfile -C callback var < ABC.csv
$
$ source nachstellen.sh
$
$ echo ${var[@]}
Name,Vorname,Alter Meier,Sven,33 Müller,Volker,47 Schulze,Frieder,63
$
Ergebnis: es wird nur newline in ein Leerzeichen umgewandelt, was mapfile aber schon von Haus aus macht. Die function bewirkt im Zusammenhang mit der Option -C also nichts. Oder habe ich bei deinem Beispiel etwas falsch verstanden?
Leider keine Änderung:
$ echo ${var[@]}
$ echo "${processed_lines[@]}"
$ source nachstellen.sh
$ echo ${var[@]}
Name,Vorname,Alter Meier,Sven,33 Müller,Volker,47 Schulze,Frieder,63
$
$ echo "${processed_lines[@]}"
$
Dann habe ich bei mapfile noch die Option -d',' mit hinzugenommen:
$ unset var
$ unset processed_lines
$ source nachstellen.sh
$ echo ${var[@]}
Name, Vorname, Alter Meier, Sven, 33 Müller, Volker, 47 Schulze, Frieder, 63
$ echo "${processed_lines[@]}"
$
Da wird dann das Komma nicht getauscht, sondern es wird zusätzlich zum Komma ein Leerzeichen hinzugefügt. Das ist aber auch nachvollziehbar, weil dann das Komma als Trenner verwendet wird. Am Ende der Zeile bleibt nach wie vor nur das schon ohne Option -C erzeugte Leerzeichen stehen.
Perfekt, das hilft mir sogar in mehr als einer Hinsicht weiter:
Danke für den Tipp. 👍