連続した数値を含む数値リストのフィルタリング

連続した数値を含む数値リストのフィルタリング

多くのテキストファイルをフィルタリングしたいです。各ファイルには長い数字のリストが含まれています。ファイルは、各数字の連続した数字に基づいてフィルタリングする必要があります。

リストの例では、次のファイルのいずれかを構成します。

入力ファイルdata.log:

12365
91738
349874
128152639
1234
7654
08767
1234567

私の考えでは:

1 - 2つの連続した数字を含む数字でこのリストをフィルタリングします。予想される出力は次のとおりです。

12365
349874
128152639
1234
7654
08767
1234567

2〜3つの連続した数字を含む数字でこのリストをフィルタリングします。予想される出力は次のとおりです。

12365
349874
1234
7654
08767
1234567

3〜4つの連続した数字を含む数字でこのリストをフィルタリングします。予想される出力は次のとおりです。

1234
7654
1234567

4〜5つの連続した数字を含む数字でこのリストをフィルタリングすると、予想される出力は次のようになります。

1234567

数字内の連続した数字の順序が最小のものから最大のもの(例:1234...など)、または大きいものから小さいもの(例:54321)の場合は、出力に含める必要があります。

ベストアンサー1

grepteeおよびを使用して、-ismsでいっぱいのトリッキーな小さな関数を作成しrevます。bash

dqs() { a=${2:-123456789} ; [ "$1" -ge 2 ] &&  
        grep -iF "$(eval eval printf '%s\\\\n' \\$\\{a:\{0..$((${#a}-$1))\}:$1\\} |
                    tee >(rev) )"
       }

テストを受けてください:

dqs 5 < data.log 
1234567
dqs 4 < data.log 
1234
7654
1234567
dqs 3 < data.log 
12365
349874
1234
7654
08767
1234567

仕組み:

printf目的の長さのシーケンスのリストを印刷します(例:123234など。)、teeミラーを取り付けます(つまり右から左へ、または後ろに)rev次に、grep -f <(...)そのリストの項目の標準入力を検索します。

このシーケンスのリストを作成するには通常、ループまたはseq両方が必要ですが、ここでは次のようにします。bash 配列表現, と結合部分文字列拡張、少し残った山水。ただし、bashインタプリタが必要な順序でこれらの操作を実行できないため、これは不可能です。だから私たちは正しい順序で仕事をするためにeval evalいくつかの戦略を使います。\\\bash

ここでは[ "$@" -gt 0 ] &&機能的には必要ありませんが、持っている方が安全です。それはそこにdqsあることを保証します1つだけ数値引数です。それ以外の場合はgrep実行されません。これはeval eval何もしません。邪悪な

ボーナス:2番目の引数を追加すると、他のシーケンスが123456789変更されてもコードは機能し続けます。たとえば、dqs 4 123456789ABCDEF4桁の16進数シーケンス(および逆順)が検索され、dqs 3 $(printf %s {a..z})3桁のアルファベットシーケンスが検索されます。

# search `man bash` for the three most popular words 
# that have 3 three char alphabetic runs
man bash | tr ' ' '\n' | sort | uniq -c | sort -gr  | 
dqs 3 $(printf '%s' {a..z}) | head -3

出力:

     92 first
     76 default
     38 environment

おすすめ記事