比赛前后的Grep角色?

时间:2011-11-12 01:05:44

标签: bash grep

使用此:

grep -A1 -B1 "test_pattern" file

将在文件中匹配的模式之前和之后生成一行。有没有办法显示不是行而是指定数量的字符?

我文件中的行非常大,所以我对打印整行不感兴趣,而只是在上下文中观察匹配。有关如何做到这一点的任何建议吗?

7 个答案:

答案 0 :(得分:146)

之前的3个字符和

之后的4个字符
$> echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}'
23_string_and

答案 1 :(得分:88)

grep -E -o ".{0,5}test_pattern.{0,5}" test.txt 

这将在您的模式之前和之后匹配最多5个字符。 -o开关告诉grep只显示匹配,-E使用扩展正则表达式。确保在表达式周围加上引号,否则shell可能会解释它。

答案 2 :(得分:29)

您可以使用

awk '/test_pattern/ {
    match($0, /test_pattern/); print substr($0, RSTART - 10, RLENGTH + 20);
}' file

答案 3 :(得分:21)

你的意思是,像这样:

grep -o '.\{0,20\}test_pattern.\{0,20\}' file

这将在test_pattern的任意一侧打印最多二十个字符。 \{0,20\}符号类似于*,但指定零到二十个重复而不是零或更多。-o表示只显示匹配本身,而不是整行。

答案 4 :(得分:1)

我永远不会轻易记住这些神秘的命令修饰符,因此我将top answer转换为~/.bashrc文件中的一个函数:


cgrep() {
    # For files that are arrays 10's of thousands of characters print.
    # Use cpgrep to print 30 characters before and after search patttern.
    if [ $# -eq 2 ] ; then
        # Format was 'cgrep "search string" /path/to/filename'
        grep -o -P ".{0,30}$1.{0,30}" "$2"
    else
        # Format was 'cat /path/to/filename | cgrep "search string"
        grep -o -P ".{0,30}$1.{0,30}"
    fi
} # cgrep()

实际情况如下:

$ ll /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

-rw-r--r-- 1 rick rick 25780 Jul  3 19:05 /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

$ cat /tmp/rick/scp.Mf7UdS/Mf7UdS.Source | cgrep "Link to iconic"

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

$ cgrep "Link to iconic" /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

有问题的文件是连续的25K行,使用常规grep找不到想要的文件。

请注意,您可以使用两种与cgrep方法相似的方式来调用grep

有一种创建函数的“更聪明”的方法,其中仅在设置时传递“ $ 2”,这将节省4行代码。我没有方便。类似于${parm2} $parm2。如果找到它,我将修改功能和此答案。

答案 5 :(得分:0)

使用gawk,您可以使用匹配功能:

    x="hey there how are you"
    echo "$x" |awk --re-interval '{match($0,/(.{4})how(.{4})/,a);print a[1],a[2]}'
    ere   are

如果您对perl没问题,可以使用更灵活的解决方案:以下将在模式之前打印三个字符,然后是实际模式,然后在模式之后打印5个字符。

echo hey there how are you |perl -lne 'print "$1$2$3" if /(.{3})(there)(.{5})/'
ey there how

这也可以应用于单词而不仅仅是字符。以下将在实际匹配字符串之前打印一个单词。

echo hey there how are you |perl -lne 'print $1 if /(\w+) there/'
hey

以下将在模式后打印一个单词:

echo hey there how are you |perl -lne 'print $2 if /(\w+) there (\w+)/'
how

下面将在模式之前打印一个单词,然后在模式之后打印一个单词:

echo hey there how are you |perl -lne 'print "$1$2$3" if /(\w+)( there )(\w+)/'
hey there how

答案 6 :(得分:0)

您可以使用regexp grep查找+用第二个grep突出显示

echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}' | grep string

23_string_and

enter image description here