1

我正在文件中查找一些字符串,我需要使用 UNIX 命令的确切位置(行号和行中的位置)。

我只能使用grep -n找到行号,但我无法获得出现次数甚至他们的位置。

我知道如何使用gregexpr函数在 R 中编写脚本来完成这一切,但我只想使用 UNIX 命令。有什么等价的吗?

4

3 回答 3

2

要获取行号和一行模式的所有位置,您可以使用以下 awk 命令:

cat file
#This is your hosts file
127.0.0.1 localhost linux 
192.168.1.2 domain1.com 
#this is added automatically to 
192.168.1.2 sub.domain1.com www.domain1.com

awk -v p='domain1' 'index($0,p) {
   printf "%s:", NR;
   s=$0; m=0;
   while((n=index(s, p))>0) {
      m+=n;
      printf "%s ", m;
      s=substr(s, n+1)
   }
   print ""
}' file
3:13 
5:17 33 

以下备用 awk 命令也应该起作用:

awk -v p='domain1' 'index($0,p) {
   printf "%s:", NR;
   l=length(p);
   s=$0;
   m=0;
   while((n=index(s, p))>0) {
      m = m ? m+n+l-1 : m+n;
      printf "%s ", m;
      s=substr(s, n+l)
   }
   print ""
}' file
3:13 
5:17 33 
于 2013-09-29T10:48:58.597 回答
2
$ cat file
now is
the winter of our
discontent

$ awk 's=index($0,"winter") { print "line=" NR, "start position=" s}' file
line=2 start position=5

如果您想查找所有出现的字符串:

$ cat file
now is
the winter (yes, winter) of our
discontent

$ cat tst.awk
BEGIN{ SLENGTH = length(string) }
{
    skipped = 0
    starts = ""
    while ( SSTART = index($0,string) ) {
        starts = starts (starts?" ":"") (skipped + SSTART)
        $0 = substr($0,SSTART + SLENGTH)
        skipped += (SSTART + SLENGTH - 1)
    }
}
starts { print "line=" NR, "start position(s)=" starts }

$ awk -v string="winter" -f tst.awk file
line=2 start position(s)=5 18

我通常不提倡使用全大写的变量名,因为它们通常表示内置变量,但在这种情况下,我想清楚地显示字符串(用户提供的 SSTART/SLENGTH)的 index() 和match() 用于正则表达式(内置 RSTART/RLENGTH)。

恕我直言,SSTART/SLENGTH 应该已内置到 index() 函数中,但我理解为什么它们没有(功能上不必要,不像 match() 的 RLENGTH,因此会产生不必要的性能影响),我怀疑此时是否会发生这种情况所以这是nbd。sidx()如果有人关心/喜欢,这是一个定义并使用 index() 函数(名称)的版本:

$ cat tst.awk
function sidx(src,tgt) {
    SLENGTH = ( (SSTART=index(src,tgt)) ? length(tgt) : 0 )
    return SSTART
}
{
    skipped = 0
    starts = ""
    while ( sidx($0,string) ) {
        starts = starts (starts?" ":"") skipped + SSTART
        $0 = substr($0,SSTART + SLENGTH)
        skipped += SSTART + SLENGTH - 1
    }
}
starts { print "line=" NR, "start position(s)=" starts }
$
$ awk -v string="winter" -f tst.awk file
line=2 start position(s)=5 18

警告:如果您传入一个空字符串作为要搜索的字符串,上述脚本将进入无限循环。如果您愿意,可以在 BEGIN 部​​分为此添加测试。

如果您想要不同的东西,请使用一些示例输入和预期输出更新您的问题并阐明您的要求。

于 2013-09-29T14:26:20.453 回答
1

您可以在这样的一行中找到确切的位置:

echo "Unix 论坛是最好的站点。" | grep -o "[-_a-zA-Z0-9.]" | grep -nx

4:x

我在这里找到:http ://www.unix.com/shell-programming-scripting/26190-finding-character-position-file.html

您可以将其与您的解决方案结合使用。

(嗯。它只适用于角色......)

于 2013-09-29T10:43:02.427 回答