Ich habe alle Verzeichnis-Tags aus einer Datei abgerufen. Jetzt stecke ich in einer Situation fest, in der ich diese ganzen einzelnen Verzeichnis-Tags in verschiedenen Variablen speichern möchte, wie unten gezeigt. Vielen Dank im Voraus.
Nachfolgend sehen Sie, was ich abgerufen habe:
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Erforderlich:
# echo $var1
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
# echo $var2
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Bitte beachten: Es gibt nicht nur 2 Verzeichnis-Tags, sondern viele Verzeichnis-Tags ohne Lücke dazwischen. Jedes einzelne Verzeichnis muss in einer eigenen Variable gespeichert werden.
Danke im voraus
Antwort1
Sie können die Zeilen der Datei durchlaufen und die neuen Zeilen zu einer Zeichenfolge hinzufügen, bis Sie auf ein </Directory>
Tag stoßen.
Wenn Sie nur Tags haben , wäre der Code viel einfacher. Wenn Sie nicht wissen, wie viele Tags Sie haben, Directory
müssen Sie varX
Variablen deklarieren, während Sie sie verwenden .declare
STR=""
i=1
DIRTAG=false
while read -r LINE; do
if grep -q '^<Directory' <<< $LINE; then
DIRTAG=true
fi
if $DIRTAG; then
STR+="$LINE
"
fi
if grep -q '^</Directory>' <<< $LINE; then
declare var$i="\"\"\"$STR\"\"\"" #You're not clear on the quotes
STR=""
i=$((i+1))
DIRTAG=false
fi
done < t.txt
Gibt nun echo "$var1"; echo "$var2"
Folgendes aus (Anführungszeichen nicht vergessen. Sonst werden Zeilenumbrüche in der gedruckten Ausgabe als Leerzeichen ausgegeben):
"""<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
"""
"""<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
"""
Wenn Sie die Anzahl der Tags nicht kennen, können Sie dies verwenden, um über die erstellten Variablen zu iterieren
for j in `seq 1 $((i-1))`; do
var=var$j
echo "${!var}"
done
Antwort2
Sie können die Datei verarbeiten, um sie in eine Liste von Variablendefinitionen umzuwandeln und diese dann als Quelle zu verwenden. Sie können beispielsweise nach jedem schließenden </Directory>
Tag eine leere Zeile hinzufügen und dann den Absatzmodus von Perl verwenden, um jeden Eintrag als einzelne Zeile zu lesen:
$ sed 's|</Directory>|</Directory>\n|' file |
perl -000 -lne 'print "var" . ++$k . "=\"$_\"";'
var1="<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>"
var2="<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>"
Und Sie könnten dies direkt als Quelle verwenden, um die Variablen in Ihrer aktuellen Shell tatsächlich festzulegen:
$ . <(sed 's|</Directory>|</Directory>\n|' file |
perl -000 -lne 'print "var" . ++$k . "=\"$_\"";' file )
$ echo "$var1"
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
$ echo "$var2"
<Directory /var/www>
AllowOverride None
Require all granted
</Directory>
Erläuterung
sed s|</Directory>|</Directory>\n|' file
: Fügen Sie nach jedem schließenden Tag eine neue Zeile hinzu</Directory>
.-000
: Dies aktiviert den „Absatzmodus“ von Perl, in dem eine „Zeile“ durch zwei aufeinanderfolgende Zeilenumbruchzeichen definiert wird, im Grunde eine Leerzeile. Anstatt echter Zeilen ist jede „Zeile“ jetzt also ein Absatz. Dadurch können wir alles zwischen der Eröffnung und dem Ende< Directory />
als einzelne Zeile behandeln, da jeder Eintrag durch eine Leerzeile getrennt ist.-lne
: Das-l
entfernt nachfolgende Zeilenumbrüche und fügt\n
jedem ein hinzuprint
. Das-n
liest die Eingabedatei zeilenweise (siehe oben, was „Zeile“ in diesem Zusammenhang bedeutet) und wendet das von angegebene Skript-e
auf jede Zeile an.print "var" . ++$k . "=\"$_\""
: Drucken Sie das gewünschte Ausgabeformat: die Zeichenfolgevar
, gefolgt von einer Zahl, die für jede verarbeitete Zeile erhöht wird (++$k
), dann=\"
("
muss maskiert werden, da\"
wir uns in einer Zeichenfolge in doppelten Anführungszeichen befinden) und der aktuellen „Zeile“ ($_
), gefolgt vom schließenden"
.. <(perl ...)
: Dies.
ist der Quellbefehl. Er liest die Datei, die Sie ihm geben, und führt deren Inhalt in der aktuellen Sitzung aus. Der<()
heißtProzesssubstitution, im Wesentlichen ermöglicht es uns, die Ausgabe eines Befehls so zu behandeln, als wäre es eine Datei. Beachten Sie, dass nicht alle Shells dies unterstützen. Wenn Ihre Shell dies nicht unterstützt, müssen Sie die Ausgabe möglicherweise in einer Datei speichern und diese Datei dann als Quelle verwenden.