como colocar todas as tags de diretório em variáveis ​​diferentes

como colocar todas as tags de diretório em variáveis ​​diferentes

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 Directorytags, o código seria muito mais simples. Você precisará declarar varXvariáveis ​​à medida que for usando declarese 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: -lremove novas linhas finais e adiciona um \na cada uma print. Lê -no arquivo de entrada linha por linha (veja acima o que "linha" significa neste contexto) e aplica o script fornecido por -ea cada linha.
  • print "var" . ++$k . "=\"$_\"": imprime o formato de saída desejado: a string varseguida 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.

informação relacionada