我有一个数字(比如说 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 的所有内容,然后将连接的结果通过管道传输到下一个命令的 stdinsort -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