Bash

使用 Bash、Perl 和 Regex 將文本文件中的變數提取到數組中

  • August 26, 2017

我想用 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,所以可能有比這更優雅的解決方案。

引用自:https://unix.stackexchange.com/questions/388195