仅在文件的一部分中查找字符串(如 grep -q)

仅在文件的一部分中查找字符串(如 grep -q)

我想编写一些 Bash 来验证配置文件中是否存在字符串。我无法更改文件格式,它属于不同的应用程序。

该文件被细分为由方括号中的字符串命名的组。

这应该是成功的:

[group1]
MyParameter
junk1
junk2

[group2]
junk3
junk4

这应该是一个错误:

[group1]
junk1
junk2

[group2]
MyParameter
junk3
junk4

我可以执行 agrep -q来验证MyParameter文件中是否存在,但如果它位于其他组中而不是位于 中group1,那么我仍然会失败。

如果MyParameter两个组中都存在,我就不会关心标记错误,只要它存在于group1.

我不能依赖行号(头、尾等)。另外,如果它足够通用而不依赖于名称group2(脚本只会知道,如果它发现另一行以方括号开头和结尾,则终止前一组),我会更高兴。

答案1

每当遇到文本处理问题时,有人会说“让我们使用 awk”。通常,他们有解决方案。

awk '
    /^\[.*\]$/ {group = $0}
    group == "[group1]" && $1 == "MyParameter" {found=1; exit}
    END {exit !found}
'

答案2

使用 GNUsed你可以做到

sed -n '/\[group1\]/,/\[group2\]/{/MyParameter/p}' input-file

MyParameter仅当它位于该部分时才会写入group1。如果后面的部分group1并不总是group2,您可以group2用代替.*

答案3

这是一个可以完成这项工作的 Perl 脚本:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 group pattern [file...]\n" if scalar @ARGV < 2;

my $group = shift;
my $pattern = shift;

my $curr_group = undef;
my $matched = 0;
while (<>) {
    if (/^\[(.*)\]/) {
        $curr_group = $1;
    }
    else {
        if (defined $curr_group and 
            $curr_group eq $group and 
            /$pattern/) 
        {   
            print "Match\n";
            $matched = 1;
        }
    }
}

if (not $matched) {
    print "No match\n";
}

答案4

if [ `egrep 'MyParameter|^\[.*\]$' file.conf | head -2 | tail -1` == "MyParameter" ]
then 
  echo Success
else 
  echo Failure
fi

相关内容