我想使用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,因此可能有比这更优雅的解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句