Ich möchte eine Bash-Funktion schreiben, die Textabschnitte zwischen Zeilen, die mit und übereinstimmen ## mode: org
, ## # End of org
in einer Datei druckt, mit einer leeren Zeile zwischen den Abschnitten. Vor dem ##
können jedoch beliebig viele Leerzeichen stehen.
Hier ist ein Beispiel für eine Datei, aus der Informationen extrahiert werden.
file: test.sh
## mode: org
## * Using case statement
## # End of org
case $arg in
("V")
echo "Author"
;;
(*)
## mode: org
## ** Silent Error Reporting Mode (SERM) in getopts
## *** Detects warnings without printing built-in messages.
## *** Enabled by colon {:} as first character in shortopts.
## # End of org
break
;;
esac
Die gewünschte Ausgabe wäre
* Using case statement
** Silent Error Reporting Mode (SERM) in getopts
*** Detects warnings without printing built-in messages.
*** Enabled by colon {:} as first character in shortopts.
Ich habe es getan mit
capture-org ()
{
sed -n '/^ *## mode: org$/,/^ *## # End of org$/s/ *//p' "$1" |
sed 's/^## mode: org$/\n## mode: org/' |
sed '/^## mode: org$/d' | sed '/^## # End of org$/d' | cut -c 3-
}
Kann man das auch eleganter machen?
Antwort1
sed '/^[[:space:]]*## mode: org$/,/^[[:space:]]*## # End of org$/!d; /^[[:space:]]*## mode: org$/d; s/^[[:space:]]*## # End of org$//g; s/^[[:space:]]*## //'
Dadurch wird alles gelöscht, was nicht innerhalb der Start- und Endmuster liegt. Anschließend wird das Startmuster entfernt und das Endmuster durch eine leere Zeile ersetzt (die zum Blocktrennzeichen wird).