Unix 在匹配下列行中的单词后提取随机模式

Unix 在匹配下列行中的单词后提取随机模式,unix,sed,awk,Unix,Sed,Awk,提取与关键字对应的家庭数据 Z1/NEW "THE_PALM" 769 121003 1545 NEW HOUSE IN SOMETHING SOMETHING SN HOUSE CLASS FIRST PSD93_PU 1579 CHAIRS WOOD SILVER SPOON GREEN GARDEN Z1/OLD "THE_ROSE" 786 121003 1343

提取与关键字对应的家庭数据

Z1/NEW "THE_PALM" 769 121003   1545     
NEW HOUSE IN
SOMETHING SOMETHING

SN                HOUSE            CLASS
FIRST             PSD93_PU         1579

CHAIRS
WOOD
SILVER SPOON
GREEN GARDEN



Z1/OLD "THE_ROSE" 786 121003   1343     
NEW HOUSE OUT
SOMETHING NEW

SN                HOUSE            CLASS
FIRST_O           PSD1000_ST       1432

CHAIRS
WOOD
GREEN GARDEN
BLACK PAINT


Z1/OLD "The_PURE" 126 121003   3097    
NEW HOUSE IN
SOMETHING OLD

SN                HOUSE            CLASS
LAST_O            JD4_GOLD         1076

CHAIRS
SILVER SPOON
我有一个很大的文件。在每一个描述的末尾都有一个关于房子的物品清单。对应于包含
银匙的房屋
,我想提取
房屋
ID,如data
PSD93_PU
和date
121003
中所示。我尝试了以下方法:

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=7 a=0 s="SILVER" infile > outfile

但问题是,关键字
SILVER
上方的行数是如此随机,以至于我无法找到解决方案

假设每个新房子都从
Z1开始

 $ awk '$1 ~ /^Z1/ { date=$4; id=""; f=0; next; } \
        $1 == "SN" { f=1; next; }                 \
        f == 1 { id=$2; f=0; next; }              \
        $1" "$2 == "SILVER SPOON" { print id,date }' file 
在新房子上,重置所有VAR并获得日期 如果SN匹配,则下一行包含id 从行中获取
id
如果找到“银匙”,请打印
id
日期
如果找不到,则会遇到新房子,并重置VAR

使用给定数据进行测试:

$ awk '$1 ~ /^Z1/ { date=$4; id=""; f=0; next; } $1 == "SN" { f=1; next; } f == 1 { id=$2; f=0; next; } $1 == "SILVER SPOON" && $2 == "SPOON" { print id,date }' file 
PSD93_PU 121003
JD4_GOLD 121003
注: 如果有人知道如何以及如果
$1==“SILVER”&&$2==“SPOON”
可以合并到一个语句中,那就太好了:)--比如:
$1,$2==“SILVER SPOON”

编辑: 可以使用
$1”“$2==“银勺”

可以省略空格并执行
$1$2==“SILVERSPOON”
,但即使
$2
为空且
$1
包含整个字符串,或者
$1
为SILVERSPO且
$2
处于启用状态,也会匹配。因此中的空格起到严格匹配的作用。

使用sed:

sed -n -e 's/^Z1[^"]*"[^"]*"[ \t]*[0-9]*[ \t]*\([0-9]*\).*/\1/p'
       -e '/^SN[ \t]*HOUSE/ { n; s/^[^ \t]*[ \t]*\([^ \t]*\).*/\1/p }'
首先,我们使用
-n
选项调用
sed
,以便告诉它只打印我们告诉它的内容

第一个命令将搜索特定模式以提取日期。该模式包括:

  • ^Z1
    :以字符串“Z1”开头的行
  • [^”]*
    :零个或多个非双引号字符
  • :双引号字符
  • [^”]*
    :零个或多个非双引号字符
  • [\t]*
    :零个或多个制表符或空格字符
  • [0-9]*
    :零位或更多位
  • [\t]*
    :零个或多个制表符或空格字符
  • \([0-9]*\)
    :零位或更多位。反斜杠括号用于捕获匹配项,即匹配项存储在辅助变量
    \1
  • *
    :零个或多个字符,有效地跳过所有字符,直到行尾
  • 然后将匹配的行替换为
    \1
    ,它保存我们捕获的内容:日期。命令后的
    p
    告诉sed打印结果

    第二行包含两个组合在一起的命令(在大括号内),因此它们仅在大括号之前的“地址”上执行。地址是一个模式,因此它在与模式匹配的每一行上执行。该模式由一行组成,该行以“SN”开头,后跟一系列空格或制表符,后跟字符串“房子”

    当模式匹配时,我们首先执行
    n
    next命令,从输入中加载下一行。然后,我们从新行中提取ID,方法类似于提取日期。要匹配的替代模式是:

  • ^[^\t]*
    :以零个或多个非空格或制表符(空白)字符开头的字符串
  • [\t]*
    :则具有零个或多个空格和/或制表符的序列
  • \([^\t]*\)
    :然后捕获一系列非空白字符
  • *
    :将匹配剩余字符,以便跳过它们
  • 替换的ID将成为捕获的ID,我们再次告诉sed将其打印出来

    这将打印出一行包含日期,后跟一行包含ID的行。如果您想要一行格式为
    ID-date
    ,您可以将sed的输出通过管道传输到另一个sed实例,如下所示:

    sed -n -e [...] | sed -e 'h;n;G;s/\n/ /'
    
    此sed实例执行以下操作:

  • 读取一行,并且
    h
    命令告诉它将该行存储到保持空间(一个辅助缓冲区)中
  • n
    命令读取下一行
  • G
    get命令将保持空间的内容附加到模式空间(工作缓冲区)中,因此现在我们有了ID行,后面是日期行
  • 最后,我们将新行字符替换为一个空格,从而将这些行合并为一行

  • 希望这对您有所帮助=)

    如果您的记录由两行或三行分隔,并且家庭项目前的行距是一致的,您可以像这样使用
    GNU awk

    awk -r 'BEGIN { RS="\n{3}\n*"; FS="\n" } /SILVER SPOON/ { split($1, one, OFS); split($6, two, OFS); print two[2], one[4] }' file.txt
    
    结果:

    PSD93_PU 121003
    JD4_GOLD 121003
    

    不,我们不会引用外部图像。请将图像内容作为代码或文本包含在您的问题中。允许使用外部图像。请参考它。我正在尝试在图像中显示原始数据。您的问题是关于使用
    sed
    awk
    进行文本处理。这两个程序都不适合提取文本om images。如果您想得到一个有用的答案,请以文本形式提供您的数据。在这里,请参考数据。好的,谢谢c00kiemon5ter,以上所有内容,我的目的已经解决了。@Learner\u unix如果这个答案或以上任何一个答案对您的解决方案有帮助,您应该将其标记为答案。此外,如果您发现一些有趣或有教育意义的答案或者一个好的选择考虑投票。