如何将所有目录标签放入不同的变量中

如何将所有目录标签放入不同的变量中

我已经从文件中获取了所有目录标签。现在,我陷入了一种情况,我想将整个单独的目录标签存储到不同的变量中,如下所示。提前致谢。

以下是我获取的内容:

<Directory />
    AllowOverride none
    Order deny, allow
    Deny from all
</Directory>
<Directory "/var/www">
    AllowOverride None
    Require all granted
</Directory>

必需的:

# echo $var1
<Directory /> 
AllowOverride none 
Order deny, allow 
Deny from all 
</Directory>

# echo $var2
<Directory "/var/www"> 
AllowOverride None  
Require all granted 
</Directory>

请注意:不只是 2 个目录标签,还有许多目录标签,它们之间没有任何间隙。每个完整的单独目录必须存储在单独的变量中。

提前致谢

答案1

您可以迭代文件的行并将新行添加到字符串中,直到遇到标记</Directory>

如果只有Directory标签,代码会简单得多。如果您不知道有多少个标签,则需要varX在使用时声明变量。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

现在echo "$var1"; echo "$var2"输出以下内容(不要忘记双引号。否则换行符在打印输出中将是空格)

"""<Directory />
AllowOverride none
Order deny, allow
Deny from all
</Directory>
"""
"""<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
"""

当您不知道标签的数量时,可以使用它来迭代创建的变量

for j in `seq 1 $((i-1))`; do
    var=var$j
    echo "${!var}"
done

答案2

您可以处理该文件以将其转换为变量定义列表,然后获取该文件。例如,您可以在每个结束</Directory>标记后添加一个空行,然后使用 Perl 的段落模式将每个条目作为单行读取:

$ 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>"

您可以直接获取它以在当前 shell 中实际设置变量:

$ . <(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>

解释

  • sed s|</Directory>|</Directory>\n|' file</Directory>:在每个结束标记后添加换行符。
  • -000:这会打开 Perl 的“段落模式”,其中“行”由两个连续的换行符定义,基本上是一个空行。因此,每个“行”现在不再是真正的行,而是一个段落。这让我们可以将开头和结尾之间的所有内容< Directory />视为一行,因为每个条目都由空行分隔。
  • -lne-l删除尾随换行符并\n为每个添加一个print。逐行读取-n输入文件(请参阅上面的“行”在此上下文中的含义)并将 给定的脚本应用于-e每一行。
  • print "var" . ++$k . "=\"$_\"":打印所需的输出格式:字符串var后跟一个数字,该数字针对每个处理的行(++$k)递增,然后=\""需要转义,因为\"我们位于双引号字符串内)和当前“行”($_)通过收盘"
  • . <(perl ...).是源命令,它将读取您提供的文件并在当前会话中运行其内容。称为<()流程替代,本质上它允许我们将命令的输出视为文件。请注意,并非所有 shell 都支持此功能,因此如果您的 shell 不支持此功能,则可能必须将输出保存到文件中,然后获取该文件。

相关内容