Perl: how to get lines between patterns in linux

2019-09-05 15:10发布

I have a file like this

number: string(200)
issueDate: datetime
expiryDate: datetime
file_path: string(200)
filename: string(200)
description: text

I am using this in perl to get ouputlike

FIELDS="number: string(200) issueDate: datetime expiryDate: datetime file_path: string(200) filename: string(200) description: text"

This is done by this command

perl -plne '$_ = "FIELDS=\""."$_" if $. == 1; $\ = " ";$_ = "\""."$_" if eof' document.txt

Now i have the full file like this

[entity]
JOHN

[BUNDLE]
mybundle

[FIELDS]
number: string(200)
issueDate: datetime
expiryDate: datetime
file_path: string(200)
filename: string(200)
description: text

Now i want the ouput to terminal like this in separate lines

ENTITY = JOHN
BUNDLE = Mybundle
FIELDS="number: string(200) issueDate: datetime expiryDate: datetime file_path: string(200) filename: string(200) description: text"

basically the variables NAME like ENTITY, BUNDLE, it should get from the file

how can i do that

3条回答
冷血范
2楼-- · 2019-09-05 15:50

You can do it with awk like this:

awk '
   /^\[entity\]/  {getline e;next}
   /^\[BUNDLE\]/  {getline b;next}
   /:/            {f=f " " $0}
   /^description/ {print "entity=" e RS "BUNDLE=" b RS "FIELDS=" f;f=""}' yourfile

Explanation:

If I fiind a line starting with [entity] I grab the following line and save as "e"

If I find a line starting with [BUNDLE], I grab the following line and save as "b"

If I find a line with a colon, I append it to "f" where I save the fields (with added spaces)

If I find a line starting with "description", I print out what I have found so far and clear the fields variable "f".

查看更多
家丑人穷心不美
3楼-- · 2019-09-05 16:14

Here's a fairly readable perl-ish version of my awk answer:

perl -ne '
   $e=<> if /^\[entity\]/;      # save entity as $e from line after [entity]
   $b=<> if /^\[BUNDLE\]/;      # save bundle as $b from line after [BUNDLE]
   if(/:/){                     # if there's a colon in the line
      chomp; $f.= " " . $_;     # .. append this field to $f
   }
   print "entity = ",$e,"BUNDLE = ",$b,"FIELDS = \"$f\"\n" if /^desc/;
' yourfile
查看更多
来,给爷笑一个
4楼-- · 2019-09-05 16:15
perl -l -00pe '$q = y|\n\r[]| |d >3 && q("); s|(\S+)\s*|$1 = $q|; $_.= $q' file

output

entity = JOHN
BUNDLE = mybundle
FIELDS = "number: string(200) issueDate: datetime expiryDate: datetime file_path: string(200) filename: string(200) description: text"
  • -l chomps newline on input and add's it when using print
  • -00 reads input in paragraphs (these are terminated by two or more newlines)
  • y|\n\r[]| |d replaces newlines with spaces, deletes \r[] chars, and returns number of how many chars were altered
  • thus $q is assigned " char only when more than 3 chars were replaced (used for FIELDS entry)
  • s||| substitution takes first non spaces chars (entity,bundle,fields), and inerts = $q after them
查看更多
登录 后发表回答