Busquei todas as tags de diretório de um arquivo. Agora, estou preso em uma situação em que desejo armazenar todas as tags de diretório individuais em diferentes variáveis, conforme mostrado abaixo. Agradecendo antecipadamente.
Abaixo está o que eu busquei:
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Obrigatório:
# echo $var1
<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
# echo $var2
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
Observação: não existem apenas 2 tags de diretório, existem muitas tags de diretório sem qualquer espaço entre elas. Cada diretório individual inteiro deve ser armazenado em uma variável separada.
Agradecendo antecipadamente
Responder1
Você pode iterar nas linhas do arquivo e adicionar as novas linhas a uma string até encontrar uma </Directory>
tag.
Se você tivesse apenas Directory
tags, o código seria muito mais simples. Você precisará declarar varX
variáveis à medida que for usando declare
se não souber quantas tags possui.
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
Agora echo "$var1"; echo "$var2"
gera o seguinte (não se esqueça das aspas duplas. Caso contrário, as novas linhas serão espaços na saída impressa)
"""<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
"""
"""<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
"""
Quando você não sabe o número de tags, você pode usar isso para iterar sobre as variáveis criadas
for j in `seq 1 $((i-1))`; do
var=var$j
echo "${!var}"
done
Responder2
Você pode processar o arquivo para convertê-lo em uma lista de definições de variáveis e, em seguida, obtê-lo. Por exemplo, você poderia adicionar uma linha vazia após cada </Directory>
tag de fechamento e então usar o modo de parágrafo do Perl para ler cada entrada como uma única linha:
$ 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>"
E você pode obter isso diretamente para definir as variáveis em seu shell atual:
$ . <(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>
Explicação
sed s|</Directory>|</Directory>\n|' file
: adicione uma nova linha após cada</Directory>
tag de fechamento.-000
: ativa o "modo de parágrafo" do Perl, onde uma "linha" é definida por dois caracteres de nova linha consecutivos, basicamente uma linha em branco. Então, em vez de linhas reais, cada “linha” agora é um parágrafo. Isso nos permite tratar tudo entre a abertura e o fechamento< Directory />
como uma única linha, já que cada entrada é separada por uma linha em branco.-lne
:-l
remove novas linhas finais e adiciona um\n
a cada umaprint
. Lê-n
o arquivo de entrada linha por linha (veja acima o que "linha" significa neste contexto) e aplica o script fornecido por-e
a cada linha.print "var" . ++$k . "=\"$_\""
: imprime o formato de saída desejado: a stringvar
seguida por um número que é incrementado para cada linha processada (++$k
), então=\"
("
precisa ser escapado, já\"
que estamos dentro de uma string entre aspas duplas) e a "linha" atual ($_
) seguida pelo fechamento"
.. <(perl ...)
: este.
é o comando fonte, ele lerá o arquivo fornecido e executará seu conteúdo na sessão atual. O<()
é chamadosubstituição de processo, essencialmente nos permite tratar a saída de um comando como se fosse um arquivo. Observe que nem todos os shells suportam isso; portanto, se o seu não suportar, talvez seja necessário salvar a saída em um arquivo e, em seguida, originar esse arquivo.