如何显示两个特定字符串之间的所有字符?

如何显示两个特定字符串之间的所有字符?

我想显示文件中字符串“xxx”和“yyy”之间的所有字符(引号不是分隔符的一部分)。我怎样才能做到这一点 ?例如,如果我输入“Hello world xxx 这是一个文件 yyy”,则输出应该是“这是一个文件”

答案1

sed您可以按如下方式使用模式匹配标志:

echo "Hello world xxx this is a file yyy" | sed 's/.*xxx \(.*\)yyy/\1/'

因此.*xxx将从头开始匹配到xxx。最好使用以下方式显示grep

在此输入图像描述

\1是一种“记住模式”,可以记住\(.*\)so 中从xxxup 到yyybut not 的所有内容yyy

最后打印记住的字符串。

答案2

这应该做你想做的事:

sed -e 's/xxx\(.*\)yyy/\1/'

这假设两个分隔符字符串位于同一行

答案3

仅当分隔符不一定位于同一行时,这个问题才有意义。它可以通过多种方式完成(甚至使用sed),但awk更灵活:

    #!/bin/sh
    awk'
    开始{发现=0; }
    /xxx/ {
        如果(!找到){
            发现=1;
            $0 = substr($0, 索引($0, "xxx") + 3);
        }
    }
    /yyy/ {
        如果(找到){
            发现=2;
            $0 = substr($0, 0, 索引($0, "yyy") - 1);
        }
    }   
        { 如果(找到){
            打印;
            如果(找到==2)
                发现=0;
        }
    }
    '

对于一行中最多有一个子字符串的情况,使用以下数据进行了简单测试:

    这是 xxx yy
    第一的
    第二年

    xxx.x
    yyy

    xxx#yyy

和这个输出(脚本是“foo”,数据是“foo.in”):

    $ cat foo.in|./foo
     yy
    第一的
    第二
    。X

    #

它的工作方式是,输入数据位于 中$0,并且 awk 按顺序匹配模式xxx和,从而允许在到达最后一步(即打印数据)的过程中yyy更改多个内容。$0

顺便说一句,这个例子不适用于

xxxxHelloyyyxxxWorldyyy

因为它只检查第一个匹配项。 Perl 脚本将给出不同的结果,因为它使用贪婪匹配而不是我在 awk 示例中使用的索引/子字符串。当然,Perl 也可以用脚本来做同样的事情。

Awk(像 Perl)是自由格式的,因此可以将命令表达为类似

awk 'BEGIN{found=0;}/xxx/{if(!found){found=1;$0=substr($0,index($0, "xxx")+3);}}/yyy/{if(found){found=2;$0=substr($0,0,index($0,"yyy")-1);}}{ if(found){print;if(found==2)found=0;}}'

但除非是为了举例,否则很少这样做。同样,sed脚本(面向行)可以组合成一行,但有一些限制。同样,复杂的脚本sed很少以这种方式处理。相反,它们被视为真实的程序(参见例子)。

进一步阅读:

答案4

xxx当和yyy不在同一行时 也适用的解决方案: cat /tmp/xxx-to-yyy| perl -ne '(/xxx/../yyy/) && print' | perl -pe 's/.*(xxx.*)/$1/' | perl -pe 's/(.*yyy).*/$1/'

不太漂亮...

切换-eperl只是在命令行上给出脚本。 and-n使其-p在输入行上循环,-p它们在脚本之后打印,但-n它们不是。所以基本上这只是通过三个 perl 循环发送文件。

..是一个范围运算符,在左侧条件返回 true 之前返回 false,在右侧条件返回 true 后返回 false,因此第一个循环将文件截断到两个字符串之间的行(两者都包含在内。最后两个 perl 命令删除了之前xxx和之后的文本yyy

相关内容