bash 从行号 grep 中提取最小值和最大值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16046197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:12:29  来源:igfitidea点击:

Extracting minimum and maximum from line number grep

bash

提问by user2150250

Currently, I have a command in a bash script that greps for a given string in a text file and prints the line numbers only using sed ...

目前,我在 bash 脚本中有一个命令,它对文本文件中的给定字符串进行 grep 并仅使用 sed 打印行号...

grep -n "<string>" file.txt | sed -n 's/^\([0-9]*\).*//p'

The grep could find multiple matches, and thus, print multiple line numbers. From this command's output, I would like to extract the minimum and maximum values, and assign those to respective bash variables. How could I best modify my existing command or add new commands to accomplish this? If using awk or sed will be necessary, I have a preference of using sed. Thanks!

grep 可以找到多个匹配项,从而打印多个行号。从这个命令的输出中,我想提取最小值和最大值,并将它们分配给相应的 bash 变量。我怎样才能最好地修改现有命令或添加新命令来完成此操作?如果需要使用 awk 或 sed,我更喜欢使用 sed。谢谢!

回答by perreal

You can get the minimum and maximum with this:

您可以通过以下方式获得最小值和最大值:

grep -n "<string>" input | sed -n -e 's/^\([0-9]*\).*//' -e '1p;$p'

You can also read them into an array:

您还可以将它们读入数组:

F=($(grep -n "<string>" input | sed -n -e 's/^\([0-9]*\).*//' -e '1p;$p'))
echo ${F[0]} # min
echo ${F[1]} # max

回答by Barmar

grep -n "<string>" file.txt | sed -n -e '1s/^\([0-9]*\).*//p' -e '$s/^\([0-9]*\).*//p'

回答by Kent

grep .... |awk -F: '!f{print ;f=1} END{print }'

回答by CaffeineConnoisseur

Here's how I'd do it, since grep -n 'pattern' fileprints output in the format line number:line contents...

这是我的方法,因为grep -n 'pattern' file以格式打印输出line number:line contents......

    minval=$(grep -n '<string>' input | cut -d':' -f1 | sort -n | head -1)
    maxval=$(grep -n '<string>' input | cut -d':' -f1 | sort -n | tail -1)

the cut -d':' -f1command splits the grepoutput around the colon and pulls out only the first field (the line numbers), sort -nsorts the numeric line numbers in ascending order (which they would already be in, but it's good practice to ensure it), then head -1and tail -1remove the first, and last value in the sorted list respectively, i.e. the minimum and maximum values and assign them to variables $minvaland $maxvalrespectively.

cut -d':' -f1命令拆分grep结肠周围输出翻出只有第一场(行号),sort -n按升序排序数字行号(他们应该已经在,但它是很好的做法,以确保它),然后head -1tail -1删除排序列表中的第一个和最后一个值,即最小值和最大值,并将它们分别分配给变量$minval$maxval

Hope this helps!

希望这可以帮助!

Edit: Turns out you can't do it the way I had it originally, since echoing out a list of newline-separated values apparently concatenates them into one line.

编辑:结果你不能按照我原来的方式来做,因为回显一系列换行符分隔的值显然将它们连接成一行。

回答by TrueY

It can be done with one process. Like this:

它可以通过一个过程完成。像这样:

awk '/expression/{if(!n)print NR;n=NR} END {print n}' file.txt

Then You can assign to an array (as perreal suggested). Or You can modify this script and assign to varables using eval

然后您可以分配给一个数组(如 perreal 建议的那样)。或者您可以修改此脚本并使用 eval 分配给变量

eval $(awk '/expression/{if(!n)print "A="NR;n=NR} END {print "B="n}' file.txt)
echo $A
echo $B

Output (file.txtcontains three lines of expression)

输出(file.txt包含三行expression

1
3