【问题标题】:Get lines between pattern1 and pattern2 into a seperate file including the line with pattern1 in shell将 pattern1 和 pattern2 之间的行放入一个单独的文件中,包括 shell 中带有 pattern1 的行
【发布时间】:2015-10-22 19:51:48
【问题描述】:

我有一个包含数千行的文本文件,如下所示

`DEFINE OBJECT('OBJECT.TOPIC') +
*  ALTDATE(2015-09-22) +
*  ALTTIME(00.56.38) +
   DESCR('topic object') +
   GET(ENABLED) +
   PUT(ENABLED) +
   PROPCTL(COMPAT) +
   TARGTYPE(TOPIC) +
   REPLACE
DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
DEFINE OBJECT('OBJECT2') +
*  ALTDATE(2015-09-22) +
*  ALTTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
DEFINE OBJECT('TCOBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT2') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('TCOBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

现在,我想获取包含匹配模式 OBJECT1 的块。

`DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

我已经尝试过使用 awk 和 sed 来获得至少第一部分。但它并没有在 pattern2 的第一场比赛之后停止。我运行这些命令只是为了至少获得第一个块..

awk '/OBJECT1/ {p=1}; p; $0=="REPLACE" {p=0}' objlist.txt > obj1list.txt 

awk '$0=="OBJECT1" {p=1}; p; $0=="REPLACE" {p=0}' objlist.txt > obj1list.txt

cat objlist.txt | sed  -n '/OBJECT1/p;/REPLACE/q' > obj1list.txt 

但这些不起作用。请帮助

根据建议的答案,我正在使用 awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\/{printf $0 RT}' 并获得所需的输出。但是现在我想从使用上述命令获得的输出中删除包含 user2 和 user3 的块。

【问题讨论】:

  • 嗨..我知道这是旧的,但是有没有办法在这个问题中获得包含 OBJECT1 的块后删除包含 user3 的块。我正在尝试 awk -vRS="[^+]\n" 'BEGIN{printf ""}/\/{printf " " $0 RT}'|sed '/^\s*$/ d' 但这不起作用

标签: linux shell awk sed


【解决方案1】:
awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\<OBJECT1\>/{printf $0 RT}' a

【讨论】:

  • 谢谢。这工作得很好。还有一个问题,无论如何我可以删除输出中的 REPLACE 吗?
  • 替换行?像这样? awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\/{if(!sub(" *REPLAC","")){$0=$0 RT}printf $0 }'一个
  • 嗨..我知道这是旧的,但是有没有办法在这个问题中获得包含 OBJECT1 的块后删除包含 user3 的块。我正在尝试使用awk -vRS="[^+]\n" 'BEGIN{printf ""}/\&lt;'user3'\&gt;/{printf " " $0 RT}'|sed '/^\s*$/d',但这不起作用。
  • 你能帮我吗?
  • 这样吗? awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\/&&!/\/{printf $0 RT}' 文件。最后你可能会添加反引号
【解决方案2】:

来救援吧! (几乎没有 sed 的帮助)

$ sed -r 's/^([^* ])/\n\1/' file | awk -v RS= '/OBJECT1/'

将打印

DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

ps。请注意,起始引号没有打印出来,因为它不在提取的行上。

对于更有针对性的匹配,您可以将引号组合为模式的一部分。但是,在 awk 中它具有特殊含义,应该加以处理。我使用以下方法。

$ ... | awk -v RS= -vq="'" '$0 ~ q"OBJECT1"q'

【讨论】:

  • 感谢您的回复,卡拉夫卡。我真的忘记了。还有其他对象在其名称 ex 中包含 OBJECT1。 TCOBJECT1 和有类似的线路。因此,它也输出该对象的行。无论如何要搜索那个确切的模式吗?
  • 为此,您可以使用引号作为模式的一部分。查看我的更新。
  • 这就是问题所在,卡拉夫卡。加上引号,输出只有DEFINE OBJECT('OBJECT1') +PROFILE('OBJECT1') +。我仍然像我原来的帖子一样输出。让我更新我的原始帖子,以便清楚我要做什么。
【解决方案3】:
awk 'BEGIN{RS="DEFINE OBJECT"}{if($1~/\('\''OBJECT1'\''\)/){print$0}}' my_file

【讨论】:

  • 仅打印包含 (OBJECT1) 的块...希望这是您想要做的
  • 嗨 Xorg,我想要 OBJECT1 后面的块。您的命令只给我包含 OBJECT1 的行。 A-Ray 的命令非常有效,可以为我提供必要的输出。
【解决方案4】:

这可能对你有用(GNU sed):

sed '/^\w/!{H;$!d};x;/\bOBJECT1\b/p;x;h;d' file

如果它不是记录的开头,则将其附加到保留空间 (HS),如果它不是最后一行,则将其删除。否则,它要么是记录的开头,要么是最后一行,在这种情况下:检查 HS 是否有所需的字符串,如果找到则打印,然后将 HS 替换为记录的开头。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2012-06-13
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多