I would like to extract variables from a text file with Bash, Perl and Regex.The file looks like this (and is already read into the variable $str):Filename: XXXXXType: XXXSize: XXXXUnimportant thing: XXXXFilename: YYYYYType: YYYSize: YYYYUnimportant thing: YYYYI need Filename, Type and Size for each block. An array would be the best but a strings containing these variables separated by a given character is also acceptable.However, sometimes some of the fields (e.g. Size or Type) is missing. I would like to omit these records, so I think I need a Regex which can match through multiple lines.I tried the following:perl -pe 's/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $strbut this printed out the original text without modification.Then I tried it without the p commandline parameter (I hoped this way the whole file will be processed instead of iterating lines):perl -e 's/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $strThis one did not print anything (empty result).Then I tried adding print in front of the Regex because I thought maybe the removal of -p caused that Perl does not know that I want the results printed:perl -e 'print s/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n/\1\t\2\t\3\n/' <<< $strStill no success (empty result).What am I missing?Update:I would like this as a one line perl command.
Extract variables from text file into array with Bash, Perl and Regex
bash;regular expression;perl
My Perl knowledge is thin but since no one else has provided a Perl answer I'll give it a go.Pass your data in as file and it will print tab-separated lines with three values per line: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; } ' infileResult:XXXXX   XXX     XXXXYYYYY   YYY     YYYYIt's a bit brute-force but works by splitting the input up into paragraphs/blocks andthen applies your multi-line regex to each.Details...while (<>) { $s .= $_; } - Slurp the input into a single string.chomp $s - Remove trailing newline from the string.@arr = split(/\n{2,}/, $s) - Split string on consecutivenewlines. This breaks it up into paragraphs/blocks. Store the blocks in an array.foreach my $a(@arr) - Loop over each array element (block). The next two lines of code are applied to each block.$a =~ s/Filename: ([^\n]*)\nType: ([^\n]*)\nSize: ([^\n]*)\n.*/$1\t$2\t$3\n/ || next -  Extract values from the three fields of interest. If no substitution occurs (meaning the regex doesn't match because, for example, a value is missing) then skip this block and move to the next one. print $a - Printthe result of the substitution: the three values separated by tabs.Again, I don't use much Perl so there probably are more elegant solutions than this.