Grepはループでパターンを繰り返します。

Grepはループでパターンを繰り返します。

2つのファイルがあります。

ファイル1:

ABA
FFR
HHI
HAB

ファイル2:

ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC

file1 の各行は、file2 の対応する行の先頭で繰り返されるパターンです。 file1で繰り返されるパターンではなく、file2の各行部分を取得したいと思います。

希望の出力:

TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC

私はこのループを使用しようとしています:

while read -r line
do

grep -v "$line{1,}"   file2.txt 

done < file1.txt

しかし、私は次のような結果を得ます。

ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC

答え1

ABA変数にegを使用すると、grep -v "$line{1,}"grepにパターンが与えられます。つまり、1つ、1つ、および少なくとも1つをABA{1,}探します。最後の反復は重要ではありません。それ以降は何もないので、1回の繰り返しでもマッチします。ABAABA

さて、デフォルトでは、grepは、次のように計算された反復をバックスラッシュで書く必要がある基本正規表現(BRE)を使用することを除いてください。拡張正規表現 (ERE) では 1 回以上の反復が発生しますが、BRE ではリテラル文字 4 つ (一般文字でもあります) です。\{n,m\}{1,}++

ただし、grepは内容全体を印刷します。ワイヤー一致または-v一致しません。行の一部を削除しません。 (grep -o一致する部分だけを印刷する場合を除いては適用されないと思います-v。)また、そのループを通して次grepのようになります。みんなパターンごとに行があるので、file2コンテンツは何度も繰り返されます。


各反復の各入力から1行を読み取るループが必要です。シェルで実行できますが、非常に遅いです。 AWKのような方が良いです。たとえば、次のようになります。

$ awk '{getline pat < "file1"; sub("^(" pat ")*", ""); print}' file2
TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC

AWKプログラムは、行(およびコマンドラインで提供されている他のファイル)を通して暗黙的に繰り返されます。ここではfile2、各反復で明示的に1行を読みます。file1次に、現在の行に一致する"^(" pat ")*"同様のパターンを構成し、それを空の文字列に置き換えます。^(ABA)*

これにより、行からパターンの追加インスタンスが削除されず、たとえばにABAABAFOOABABARなりますFOOABABAR。その項目も削除するにはに変更しますgsub("(" pat ")*", "");

答え2

使用されたソリューションは、awk各行の対応する行から繰り返されるパターンを削除します。file1file2

awk 'NR==FNR { pattern[NR]="^(" $0 ")*"; next } { sub(pattern[FNR], ""); print }' file1 file2

説明する:

  • NR==FNR最初のファイルのみが一致する条件です。
  • pattern[NR]="^(" $0 ")*";文字列でパターンを構成し、現在の行番号をインデックスとして配列に追加します。ABA-> =^\(ABA\)*行の先頭に繰り返される文字列の数。ABA
  • nextすべての追加処理をスキップします。これにより、次の操作は2番目(および後続)のファイルにのみ適用されます。
  • sub(pattern[FNR], "")現在の行番号を空の文字列に置き換えるパターン
  • print(修正された)行を印刷してください

考えられる解決策はこれを使用して、すべての行のすべてのパターンをawk削除します。file1file2

awk 'NR==FNR { pattern[count++]="^(" $0 ")*"; next } { for(i = 0; i < count; i++) sub(pattern[i], ""); print }' file1 file2

説明する:

  • NR==FNR最初のファイルのみが一致する条件です。
  • pattern[count++]="^(" $0 ")*";文字列でパターンを整理し、それを配列に追加します。ABA-> =^(ABA)*行の先頭に繰り返される文字列の数。処理された行数。ABAcountfile1
  • nextすべての追加処理をスキップします。これにより、次の操作は2番目(および後続)のファイルにのみ適用されます。
  • for(i = 0; i < count; i++)すべてのパターンを循環します。
  • sub(pattern[i], "")パターンを空の文字列に置き換える
  • print(修正された)行を印刷してください

答え3

while read-bash-loop メソッドによると、sed次の手法を実装できます。

#!/bin/bash
i=0
while read pat ; do
    ((i++))
    sed -n "${i}s/^\($pat\)\{1,\}//g;${i}p" file2
done < file1

「繰り返しパターン」の説明は少し混乱しています。少なくとも2回は現れるべきだと思います。たとえば、\{2,\}私はそれがより適切であると感じるでしょう。

答え4

それだけです、友達:

challenge.sh

#!/bin/bash
readarray -t searchStrs < file1.txt
linesInFile=$((${#searchStrs[@]} - 1))
line=0
while [ ${line} -le ${linesInFile} ]
do
        srchStr=$(echo ${searchStrs[$line]})
        result=$(grep -E "^${srchStr}" file2.txt | sed "s@${srchStr}@@g")
        line=$((${line} + 1))
        echo ${result}
done
./challenge.sh
TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
cat file2.txt
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC

関連情報