【问题标题】:Match a text in a file and print text above that matching another pattern匹配文件中的文本并在匹配另一个模式的上方打印文本
【发布时间】:2021-03-21 19:01:07
【问题描述】:

我有一个文件,类似这样的

|| SUMMERCAMP ||
| Martin Mayer |
| Hunter David |
| Vanessa Lawrence |
| Jake Corper |
| Claudia Jones |

|| Discoparty ||
| Pavel Chavetzny |
| Julian Tannenbaum |
| Cord Kruger |
| Jennifer Lowenstein |

我现在想要匹配,假设是 Claudia Jones,我想要结果 ||夏令营 || (我不需要管道)。我只需要匹配一行并从那里向上搜索,直到我匹配到例如||,然后打印该行。如果匹配 Cord Kruger,我需要 ||不和谐 ||结果(同样有或没有管道)。试过sed,没有用。非常感谢所有帮助。

我尝试过使用

awk -F \| '/^\|{2}/ { grp=$1;next } $1=="$groupmember" { print "||"grp"||" }' $GROUPSRC

例如(根据 Raman 所说),其中 $GROUPSRC 是我正在搜索的文件,$groupmember 是我在 while 读取循环中提供给脚本的变量。

我也试过

grep -B 10

但这不起作用,因为接下来的 10 行会向上看,有时我没有“||”在那些,或者我有不止一个,这当然会扰乱结果。

感谢到目前为止的回答,很抱歉没有提出更明确的问题。

【问题讨论】:

  • 你能展示你的尝试吗?
  • 另一种方式,利用ed在文件中向后搜索的能力:printf "%s\n" '/User 4/;?GROUP?;.p' | ed -s yourfile(搜索匹配User 4的第一行,然后从该行向后搜索匹配GROUP,并打印该行。)
  • 重新表述问题以使其更清楚,并包括我尝试过的示例,我们可以重新打开它吗?

标签: bash sed


【解决方案1】:

使用 awk:

 awk -F \| -v usr="Claudia Jones" '/^\|{2}/ { grp=$3;next } $2==" "usr" " { print "||"grp"||" }' file

将字段分隔符设置为“|”并将变量 usr 设置为 4。然后当行以 2 "|" 开头时,将变量 grp 设置为第三个分隔字段并跳到下一行。当第二个字段等于“用户”后跟传递的 usr 变量,然后是另一个空格时,使用“||”打印 grp 变量前缀和附加。

【讨论】:

  • 我试过这个(检查上面),但要么我太缺乏经验,要么有别的东西,这个awk的结果总是保持空白。
  • 是的。自从我发布原始答案以来,您更改了示例数据。尝试修改。
  • 我知道我做到了,拉曼。不是出于恶意。问题结束了,我意识到我应该让它更精确。道歉。
  • 感谢拉曼,你是 100% 正确的,它有效 :)
【解决方案2】:

Perl 来救援!

perl -ne '$g = $_ if /GROUP/; print $g if /User 4$/' file
  • -n逐行读取输入并运行每一行的代码;
  • $_ 包含当前行,如果行包含GROUP,我们将其存储在变量$g 中;
  • 如果该行包含User 4,我们将打印存储的组。美元符号表示“字符串结尾”,此处需要不匹配 User 42 等。

【讨论】:

    【解决方案3】:

    如果您的记录之间有空行,您可以使用awk 这样做:

    awk '/User 4/ { print $1 }' RS= FS='\n' < infile
    

    输出:

    || GROUP 1 ||
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 2017-10-29
      • 1970-01-01
      • 2019-05-10
      • 2021-04-02
      相关资源
      最近更新 更多