我已经从文件中获取了所有目录标签。现在,我陷入了一种情况,我想将整个单独的目录标签存储到不同的变量中,如下所示。提前致谢。
以下是我获取的内容:
<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 不支持此功能,则可能必须将输出保存到文件中,然后获取该文件。