複数行のテキストパターンに一致するスクリプト?

複数行のテキストパターンに一致するスクリプト?

私の変数には複数行の文字列があります$PAT$PATファイル内で検索する必要があります$FILE。その場合は、削除されたファイル$PAT$FILE印刷する必要があります$PAT。見つからないと$PAT何も印刷されません。$PAT特殊文字が含まれており、文字通り一致する必要があるかどうかはわかりません。たとえば、$PAT裏側//\/\\|*で正確に同じ8文字の文字列を検索する必要があります$FILE

実際の使用は、既存のファイル/スクリプトにテキストをインストールして削除することです。$PATに追加するには、以前に追加された$FILEかどうかを知りたいです。$PAT既にある場合$FILE、なしで出力すると$PAT簡単に除去できます。

(Androidデバイス)にこれらのスクリプトが必要な唯一のシステムはBusyBoxです。 Perlや他のスクリプト言語はありません。

ベストアンサー1

完全な行を一致させたい場合は、$PAT解決策があります。完全な行とは、一致する場合は$FILE3つのサブファイル(f1、f2、およびf3)に分割できることを意味します。

  • cat f1 f2 f3はい$FILE
  • f2は$PAT

f1 および/または f3 は空にすることができます。

まず、f2ファイルを作成します。

cat << EOF > f2
$PAT
EOF

次に、$ FILEとf2を比較し、結果を保存します。

diff $FILE f2 > diff_res
res=$?

0の場合、$resf1とf3は空で、$ FILEは$ PATと同じです。この場合、空のファイルが欲しいとします。

diff_res""で始まる行が含まれている場合、>f2には少なくとも$ FILEにない行が含まれます。テストを受けてください:

grep -q '^> ' diff_res
test $? -eq 0 && echo "PAT not found"

diff_res" "で始まる行が含まれていない場合、f2>のすべての行は$ FILEにありますが、連続していない可能性があります。連続型の場合、diff_res以下が含まれます。

  • ""で始まらない限り、行<(f1またはf3が空の場合)
  • 2行は ""で始まらず、<最初の行は常に1d""または"1、"で始まります。

これをテストするには、次のものがあります。

nb=$(grep -v "^< " diff_res | wc -l)
if test $nb -gt 2; then
  pat_found=0
elif test $nb -eq 1; then
  pat_found=1
else
  pat_found=$(sed -n -e '1{/^1d/p;/^1,/p}' diff_res | wc -l)
fi

その後、pat_foundが1の場合、$ PATを持たないファイルはdiffの結果になります。これには<" "で始まり、次の2文字のない行のみが含まれます。

grep '^< ' diff_res | cut -c 3-

完全で再構成されたスクリプトは次のとおりです。

# Output the desired result on stdin.

f2=/tmp/f2              # Use of PID or mktmp would be better'
diff_res=/tmp/diff_res  # Use of PID or mktmp would be better'

cat << EOF > $f2
$PAT
EOF

diff $FILE $f2 > $diff_res
if test $? -ne 0; then
  grep -q '^> ' $diff_res
  if test $? -ne 0; then
    nb=$(grep -v "^< " $diff_res | wc -l)
    if test $nb -eq 1; then
      grep '^< ' $diff_res | cut -c 3-
    elif test $nb -eq 2; then
      pat_found=$(sed -n -e '1{/^1d/p;/^1,/p}' $diff_res | wc -l)
      test $pat_found -eq 1 && grep '^< ' $diff_res | cut -c 3-
    fi
  fi
fi

rm -f $f2 $diff_res

おすすめ記事