0

どうすれば次のことを達成できるのだろうと思っていました: 例として、以下を含むファイルがあります:

猿
ロバ
チキン
うま

そして、私はそれをgrepしたいのでgrep "horse\|donkey\|chicken"、これは私に与えます:

ロバ
チキン
うま

しかし、私が実際に欲しいのは次のとおりです。

うま
ロバ
チキン

だから、私はそれを私の「正規表現」の順にしたい。man ページを確認しましたが、そのためのパラメーターが見つかりませんでした。これは可能ですか(grepを使用)?

4

5 に答える 5

2

を使用してこのソリューションを試してくださいperl。多くの点で失敗する可能性があり、選択肢が 9 つ以下であったり|、式に含まれていないなど、重大な制限があります。これは、スクリプトが各単語を括弧で囲み$1$2、 などで一致を探すためです。

の内容script.pl:

#!/usr/bin/env perl

use warnings;
use strict;

my (%matches, %words);

die qq|Usage: perl $0 <input-file> <regular-expression-PCRE>\n| unless @ARGV == 2;

my $re = pop;

## Assign an ordered number for each subexpression.
do {
    my $i = 0;
    %words = map { ++$i => $_ } split /\|/, $re;
};

## Surround each subexpression between parentheses to be able to select them
## later with $1, $2, etc.
$re =~ s/^/(/;
$re =~ s/$/)/;
$re =~ s/\|/)|(/g;

$re = qr/$re/;

## Process each line of the input file.
while ( <> ) { 
    chomp;

    ## If it matches any of the alternatives, search for it in any of the
    ## grouped expressions (limited to 9).
    if ( m/$re/o ) { 
        for my $i ( 1 .. 9 ) { 
            if ( eval '$' . $i ) { 
                $matches{ $i }++;
            }   
        }   
    }   
}

## Print them sorted.
for my $key ( sort keys %matches ) { 
    printf qq|%s\n|, $words{ $key } for ( 1 .. $matches{ $key } );
}

データを仮定するinfileと:

monkey
donkey
chicken
horse
dog
cat
chicken
horse

次のように実行します。

perl script.pl infile 'horse|donkey|chicken'

これにより、次の結果が得られます。

horse
horse
donkey
chicken
chicken
于 2013-02-20T17:43:27.347 に答える
1

これには awk を使用することもできます。次の例では、一致するパターンをop配列に収集し、ENDルールの元の順序で出力します。

パターン順grep.awk

BEGIN { split(patterns, p) }

{ 
  for(i=1; i<=length(p); i++)
    if($0 ~ p[i])
      op[p[i]] = $0
}

END {
  for(i=1; i<=length(p); i++)
    if(p[i] in op) 
      print op[p[i]]
}

次のように実行します。

awk -v patterns='horse chicken donkey' -f pattern-ordered-grep.awk infile

出力:

horse
chicken
donkey

一致する行ではなくパターンのみを出力する場合は、最後のコード行を に置き換えprint p[i]ます。

于 2013-02-20T20:47:24.387 に答える
1

必要な文字列の配列を作成するだけで、各文字列が見つかったら、配列内の次の要素のチェックに進みます。

$ cat tst.awk
BEGIN{ numStrings = split("horse donkey chicken",strings) }
$0 == strings[numFound+1] { numFound++ }
numFound == numStrings { print "Found them all!"; exit }

$ cat file2           
monkey
horse
donkey
chicken

$ awk -f tst.awk file2
Found them all!

$ cat file            
monkey
donkey
chicken
horse

$ awk -f tst.awk file
$
于 2013-02-21T16:46:52.500 に答える
0

これはどう?

cat file1.txt | grep -e horse -e donkey -e chicken | sort -r
horse
donkey
chicken
于 2013-02-20T17:20:06.560 に答える