我已經從文件中獲取了所有目錄標籤。現在,我陷入了一種情況,我想將整個單獨的目錄標籤儲存到不同的變數中,如下所示。提前致謝。
以下是我獲取的內容:
<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 不支援此功能,則可能必須將輸出儲存到檔案中,然後取得該檔案。