Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何像grep-B这样只选择一行?_Linux_Bash_Shell_Scripting - Fatal编程技术网

Linux 如何像grep-B这样只选择一行?

Linux 如何像grep-B这样只选择一行?,linux,bash,shell,scripting,Linux,Bash,Shell,Scripting,一切都在标题里。基本上,假设我有这个图案 some text lalala another line much funny wow grep 我觉得很有趣,我希望我的输出是“拉拉” 谢谢你一个可能的答案是使用ed或ex来实现这一点(在它们中这是微不足道的): 唯一的问题是,如果您试图处理标准输入而不是文件;然后必须将标准输入保存到文件并处理该文件,这会破坏并发性 您不能在sed中进行负偏移(虽然GNUsed允许您进行正偏移,因此您可以使用sed-n'/lalala/,+2p'文件根据查找“l

一切都在标题里。基本上,假设我有这个图案

some text lalala
another line 
much funny wow grep
我觉得很有趣,我希望我的输出是“拉拉”


谢谢你

一个可能的答案是使用
ed
ex
来实现这一点(在它们中这是微不足道的):

唯一的问题是,如果您试图处理标准输入而不是文件;然后必须将标准输入保存到文件并处理该文件,这会破坏并发性

您不能在
sed
中进行负偏移(虽然GNU
sed
允许您进行正偏移,因此您可以使用
sed-n'/lalala/,+2p'文件
根据查找“lalala”来获取“lalala”到“funcy”行(这不是您想要的),但无法根据查找“funcy”找到“lala”行。标准
sed
完全不允许偏移

如果只需要打印模式匹配行之前第8行中找到的IP地址,则需要稍微复杂一点的
ed
脚本,但仍然可以:

ed - yourfile <<< 'g/funny/.-8s/.* //p'

ed-yourfile由于
grep-B
仅在匹配前打印每一行的完整数字,因此您必须将输出导入类似grep或Awk的内容

grep -B 2 "funny" file|awk 'NR==1{print $NF; exit}'
你也可以用Awk

awk -v s="funny" '/[[:space:]]lalala$/{n=NR+2; o=$NF}NR==n && $0~s{print o}' file
对于IP地址的具体示例,如您的评论中所述,匹配前8行:

awk -v s="funny" '
/[[:space:]][0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ {
    n=NR+8
    ip=$NF
}
NR==n && $0~s {
    print ip
}' file

这些Awk解决方案首先找到您可能需要的输出字段,然后仅当您想要的单词存在于下一行中时才打印输出。

这里尝试一种稍微通用的Awk解决方案。它维护最后
q
行的循环队列,并在看到匹配时在队列的最前面打印该行

#!/bin/sh
: ${q=8}
e=$1
shift
awk -v q="$q" -v e="$e" '{ m[(NR%q)+1] = $0 }
    $0 ~ e { print m[((NR+1)%q)+1] }' "${@--}"
适应不同的默认设置(我将其设置为8)或正确的选项处理(目前,您可以像
q=3./qgrep regex file
那样运行它)以及记住(并因此打印)整行应该足够简单


(如果您在第一行
q
-1中看到匹配,我也不想让它正常工作。它只会打印一个空行。)

是“拉拉”还是整行?你是只想要一行写着“拉拉”呢,还是随便哪一行正好是前面两行(即使它不包含“拉拉”)?是的,只是拉拉。在我的情况下,它是一个ip地址。我所需要做的就是得到ip地址,它在我grep行的末尾上方8行。当你不习惯所有的工具,例如cut、sed、grep等时,这有点困难。我正在处理它,但这一个很困难
awk -v s="funny" '
/[[:space:]][0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ {
    n=NR+8
    ip=$NF
}
NR==n && $0~s {
    print ip
}' file
#!/bin/sh
: ${q=8}
e=$1
shift
awk -v q="$q" -v e="$e" '{ m[(NR%q)+1] = $0 }
    $0 ~ e { print m[((NR+1)%q)+1] }' "${@--}"