Bash
使用 Bash、Perl 和 Regex 將文本文件中的變數提取到數組中
我想用 Bash、Perl 和 Regex 從文本文件中提取變數。
該文件看起來像這樣(並且已經讀入變數 $str):
Filename: XXXXX Type: XXX Size: XXXX Unimportant thing: XXXX Filename: YYYYY Type: YYY Size: YYYY Unimportant thing: YYYY
我需要每個塊的文件名、類型和大小。數組是最好的,但包含這些變數並由給定字元分隔的字元串也是可以接受的。
但是,有時某些欄位(例如大小或類型)會失去。我想省略這些記錄,所以我認為我需要一個可以匹配多行的正則表達式。
我嘗試了以下方法:
perl -pe 's/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $str
但這在沒有修改的情況下列印出原始文本。
然後我在沒有 p 命令行參數的情況下嘗試了它(我希望這樣處理整個文件而不是迭代行):
perl -e 's/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $str
這個沒有列印任何東西(空結果)。
然後我嘗試在正則表達式前面添加列印,因為我認為可能刪除 -p 導致 Perl 不知道我想要列印結果:
perl -e 'print s/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $str
仍然沒有成功(空結果)。
我錯過了什麼?
更新:
我希望這是一個單行 perl 命令。
我的 Perl 知識很薄,但由於沒有其他人提供 Perl 答案,我會試一試。
將您的數據作為文件傳遞,它將列印製表符分隔的行,每行三個值:
perl -e 'while (<>) { $s .= $_; } chomp $s; @arr = split(/\n{2,}/, $s); foreach my $a(@arr) { $a =~ s/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n.*/$1\t$2\t$3\n/ || next; print "$a"; } ' infile
結果:
XXXXX XXX XXXX YYYYY YYY YYYY
這有點蠻力,但通過將輸入分成段落/塊然後將多行正則表達式應用於每個段落/塊來工作。
細節…
while (<>) { $s .= $_; }
- 將輸入轉換為單個字元串。chomp $s
- 從字元串中刪除尾隨換行符。@arr = split(/\n{2,}/, $s)
- 在連續換行符上拆分字元串。這將其分解為段落/塊。將塊儲存在數組中。foreach my $a(@arr)
- 循環遍歷每個數組元素(塊)。接下來的兩行程式碼應用於每個塊。$a =~ s/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n.*/$1\t$2\t$3\n/ || next
- 從感興趣的三個欄位中提取值。如果沒有發生替換(意味著正則表達式不匹配,例如,缺少某個值),則跳過此塊並移至下一個塊。print "$a"
- 列印替換結果:由製表符分隔的三個值。同樣,我不使用太多 Perl,所以可能有比這更優雅的解決方案。