给定一些数字,使用 grep 来查找该数字在编号列表中的位置?

给定一些数字,使用 grep 来查找该数字在编号列表中的位置?

我有一个数字(比如说 13),我想在一个不完整的编号列表中找到它的位置。以下是一个示例列表:

1
3
4
5
9
16
17
21

显然 13 应该位于 9 和 16 之间,但是如果我有 13 这个数字,我该如何 grep 下一个最高数字呢?即如果我有 13,我该如何为 16 创建 grep 呢?

我之所以询问是因为我想使用 sed 或 awk 根据搜索参数插入一行,但我不知道如何使用 grep 来找到位置。

如果我需要澄清的话请告诉我,因为这对我来说有点难以解释。

答案1

也许不是您想要的,但是当您实际上试图插入一个值时,我会亲自将该数字附加到列表中,然后使用它sort -n来将事物按正确的顺序排列。

这样的命令可能看起来像这样(如果列表在文件中):

echo 13 | cat listfile - | sort -n | sed '/^$/d' | cat - > listfile

(将 13 替换为您要插入的数字,可能是变量x,因此命令序列将以 开头echo $x |

为了解释,我将其分为以下几个部分:

  • echo 13 |将数字 13 输出到 stdout,然后通过管道传输到下一个命令
  • cat listfile - |首先获取列表文件的内容,然后获取从 stdin 到 EOF 的所有内容,然后将连接的结果通过管道传输到下一个命令的 stdin
  • sort -n |采用管道列表并根据输入的数字性质对其进行排序(由 -n 开关给出,另请参阅man sort
  • sed '/^$/d' |删除字符串中的所有空行,然后再次转发
  • cat - > listfile将整个文件重新放回 listfile。是的,这有效,而不像 那样sed 's/a/b/g somefile > somefile'会清空文件。

如果您想将其拆分为多个命令,则可以通过始终操作文件使其更清晰易读:

echo 13 >> listfile
sort -n listfile
sed -i '/^$/d' listfile

如果您需要添加多个条目,这也会很方便。只需将它们全部附加,然后排序(这可能比每次搜索插入位置更快)。


如果您操作的是变量,上述命令同样有效。为此,var 的内容必须以使用换行符分隔的字符串形式呈现,以便可以按行排序。

如果值以空格分隔,则可以使用以下命令

list=$(echo $list 13 | sed -r 's/\s+/\n/g' | sort -n | sed '/^$/d')

除了变量赋值之外,唯一的新命令是 first sed,它将任何连续的空格字符序列(包括换行符)替换为换行符以创建行分隔符。在变量赋值中,列表将自动转换回空格分隔符。

答案2

据我所知,除非你知道你得到的数字旁边的数字范围,否则几乎不可能猜出。例如,下一个数字可能是 14,可能是 50,可能是 1000。如果你知道下一个数字的范围,那么你可以轻松做到:

$ grep -E -m 1 "1[4-9]|2[0-9]|3[0-9]|4[0-9]" file.txt
16

这里我搜索大于 13 的数字,范围是 14 <= NUM​​ <= 49。-m 1确保grep在找到第一个匹配项后停止,在本例中是文件中 13 之后的下一个数字。

编辑:如果你不确定,你可以尝试这个脚本:

#!/bin/bash
i=14
while :; do
    grep "$i" file.txt 2>/dev/null && break || i=$((i+1))
done

设置i为您得到的数字加 1。它将在文件中搜索大于 13 的数字,如果找到,则显示该数字并且操作结束,否则该数字将加一并且搜索将继续。

答案3

如果要awk插入某些内容,请直接使用它:

awk 'flag { print "I am inserting stuff"; flag = 0} $1 > 13 && !seen {flag = 1; seen = 1} 1'

以你的例子来说:

$ awk 'flag { print "I am inserting stuff"; flag = 0} $1 > 13 && !seen {flag = 1; seen = 1} 1' foo
1
3
4
5
9
16
I am inserting stuff
17
21

相关内容