【问题标题】:Perl: how to get lines between patterns in linuxPerl:如何在 linux 中获取模式之间的线条
【发布时间】:2014-03-13 11:28:14
【问题描述】:

我有一个这样的文件

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

我在 perl 中使用它来获得类似输出

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

这是通过这个命令完成的

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

现在我有了这样的完整文件

[entity]
JOHN

[BUNDLE]
mybundle

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

现在我希望像这样在单独的行中输出到终端

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

基本上是ENTITY、BUNDLE等变量NAME,应该从文件中获取

我该怎么做

【问题讨论】:

  • 您是否有意在= 周围有两行空格,而不是第三行?另外,您是否只想为多行条目添加引号?
  • 如果你不把它写成单行,写一个可读性好的 perl 脚本会更容易。 if/else/while 和长变量名有助于提高可读性

标签: regex linux perl shell centos


【解决方案1】:
perl -l -00pe '$q = y|\n\r[]| |d >3 && q("); s|(\S+)\s*|$1 = $q|; $_.= $q' file

输出

entity = JOHN
BUNDLE = mybundle
FIELDS = "number: string(200) issueDate: datetime expiryDate: datetime file_path: string(200) filename: string(200) description: text"
  • -l 在输入时选择换行符并在使用 print 时添加它
  • -00 读取段落中的输入(这些由两个或多个换行符终止)
  • y|\n\r[]| |d 用空格替换换行符,删除 \r[] 字符,并返回更改的字符数
  • 因此,$q 仅在替换超过 3 个字符时才被分配 " 字符(用于 FIELDS 条目)
  • s||| 替换首先采用非空格字符(实体、捆绑、字段),然后在它们之后惰性 = $q

【讨论】:

  • chomp 和最后一个打印换行符可以通过在-00 开关前添加-l 来删除。
  • 你能解释一下每个部分在做什么
【解决方案2】:

你可以像这样用 awk 做到这一点:

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

解释

如果我找到以 [entity] 开头的行,我会抓取以下行并另存为“e”

如果我找到以 [BUNDLE] 开头的行,我会抓取以下行并另存为“b”

如果我找到带有冒号的行,我会将其附加到“f”中,并在其中保存字段(添加空格)

如果我找到以“description”开头的行,我会打印出我目前找到的内容并清除字段变量“f”。

【讨论】:

    【解决方案3】:

    这是我的 awk 答案的一个相当易读的 perl-ish 版本:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 2019-09-28
      • 1970-01-01
      • 2016-12-19
      • 2020-09-11
      • 1970-01-01
      相关资源
      最近更新 更多