Obtuve todas las etiquetas del directorio de un archivo. Ahora, estoy atrapado en una situación en la que quiero almacenar todas las etiquetas de directorio individuales en diferentes variables, como se muestra a continuación. Agradeciendo de antemano.
A continuación se muestra lo que he obtenido:
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Requerido:
# echo $var1
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
# echo $var2
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Tenga en cuenta: no hay solo 2 etiquetas de directorio, hay muchas etiquetas de directorio sin ningún espacio entre ellas. Cada directorio individual completo debe almacenarse en una variable separada.
agradeciendo de antemano
Respuesta1
Puede iterar sobre las líneas del archivo y agregar las nuevas líneas a una cadena hasta que encuentre una </Directory>
etiqueta.
Si solo tienes Directory
etiquetas, el código sería mucho más sencillo. Deberá declarar varX
variables a medida que las utilice declare
si no sabe cuántas etiquetas tiene.
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
Ahora echo "$var1"; echo "$var2"
genera lo siguiente (no olvide las comillas dobles. De lo contrario, las nuevas líneas serán espacios en la salida impresa)
"""<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
"""
"""<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
"""
Cuando no sepa la cantidad de etiquetas, puede usar esto para iterar sobre las variables creadas.
for j in `seq 1 $((i-1))`; do
var=var$j
echo "${!var}"
done
Respuesta2
Puede procesar el archivo para convertirlo en una lista de definiciones de variables y luego obtenerlo. Por ejemplo, podría agregar una línea vacía después de cada </Directory>
etiqueta de cierre y luego usar el modo de párrafo de Perl para leer cada entrada como una sola línea:
$ 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>"
Y podrías obtenerlo directamente para configurar las variables en tu shell actual:
$ . <(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>
Explicación
sed s|</Directory>|</Directory>\n|' file
: agrega una nueva línea después de cada</Directory>
etiqueta de cierre.-000
: esto activa el "modo de párrafo" de Perl, donde una "línea" se define mediante dos caracteres de nueva línea consecutivos, básicamente una línea en blanco. Entonces, en lugar de líneas reales, cada "línea" ahora es un párrafo. Esto nos permite tratar todo lo que hay entre la apertura y el cierre< Directory />
como una sola línea, ya que cada entrada está separada por una línea en blanco.-lne
:-l
Elimina las nuevas líneas finales y agrega un\n
a cada unaprint
. Lee-n
el archivo de entrada línea por línea (consulte más arriba lo que significa "línea" en este contexto) y aplica el script proporcionado por-e
a cada línea.print "var" . ++$k . "=\"$_\""
: imprime el formato de salida deseado: la cadenavar
seguida de un número que se incrementa para cada línea procesada (++$k
), luego=\"
("
debe escaparse ya\"
que estamos dentro de una cadena entre comillas dobles) y la "línea" actual ($_
) seguida por el cierre"
.. <(perl ...)
:.
es el comando fuente, leerá el archivo que le proporcione y ejecutará su contenido en la sesión actual. el<()
se llamasustitución de procesos, esencialmente nos permite tratar la salida de un comando como si fuera un archivo. Tenga en cuenta que no todos los shells admiten esto, por lo que si el suyo no lo admite, es posible que deba guardar el resultado en un archivo y luego obtener ese archivo.