ファイルから長い文字列を削除する

ファイルから長い文字列を削除する

私のサーバー上のファイルが破損しています。 13000個の文字列を含むすべてのPHPファイルからそれらを削除したいと思います。

文字列は次のとおりです。

?php if(!isset($GLOBALS["\x61\156\x75\156\x61"])) { $ua=strtolower($_SERVER[ ... $qhroczocgv=$qjhvvbyvyv; $qhroczocgv=(729-608); $boxknervrr=$qhroczocgv-1; ?>

簡潔さのために省略記号を挿入しました。

検索文字列を使用grepすると

grep: \![]$ をエスケープしたにもかかわらず、間違った逆参照」

まず、文字列全体を含むすべてのファイルを見つけて、各ファイルからテキストを削除するにはどうすればよいですか?

答え1

コーディング規則が良いと仮定すると、特定のサイズより大きい行を削除します。

shopt -s extglob nullglob
sed -i.bak -r '/.{10000}/d' **/*.php

@wildcardの場合:

find . -name '*.php' -print0 | while IFS= read -rd "" file; do
    before=$(wc -l < "$file")
    after=$(sed -r '/.{10000}/d' "$file" | wc -l)
    case $(( diff = before - after )) in
        0) :;;  # no-op
        *) echo "will remove $diff lines from $file";;
    esac
done

答え2

fgrepまたはを試してくださいgrep -F。これにより、パターンが固定文字列として解釈されます。

また、その単一の文字列をファイルに(それ自体で)置き、それを使用してgrep -f filenameファイルを指定することもできます。ただし、まだフラグが必要です-F

他のオプションを参照してくださいman grep。便利なオプションがいくつかあります。

特定のパターンに一致する行を削除するさまざまな方法については、次を参照してください。https://stackoverflow.com/a/5413132/5419599

1つのアプローチは次のとおりです。

  1. このテキスト行を別のファイルに入れます。これを「スキーマファイル」と呼びます。
  2. 走るgrep -lrFf patternfile . > filelist
  3. filelistこの行を削除するには編集してください。./patternfile
  4. 走るfor i in $(cat filelist) ; do grep -vf patternfile $i > temp && chmod --reference=$i temp && mv temp $i ; done

ステップ2では、grepオプションは次のとおりです。-l一致するファイルを一覧表示し、一致するパターン-r-F固定文字列を使用し、-f一致patternfileする> filelistファイルのリストを含むファイルを作成します。

ステップ4では、フラグをgrep使用して印刷します。-vいいえ行を一致させ、chmod権限の問題がないことを確認し、mvファイルを所定の位置に戻します。

もっと良い方法があるかもしれませんが、これだけで十分だと思います。

編集:rootとして実行すると、ルートがこれらのファイルをすべて所有しているわけではありません。ステップ4の次のリビジョンを実行します。

for i in $(cat filelist) ; do grep -vf patternfile $i > temp && chown --reference=$i temp && chmod --reference=$i temp && mv temp $i ; done

すべてのファイルの所有者の場合、最初の4つのステップは問題ありません。

答え3

文字列がファイル内で非常に一意であると仮定すると、正規表現を使用して文字列の注目すべき部分を見つけ、afindとaを使用してsed replace切り替えることができます。

 find . -name "*.php" -exec sed -i 's/?php.*strtolower.*qhroczocgv.*boxknervrr.*-1; ?>//g' {} \;

しかし、その場に空行が残ります。

この文字列が1行に存在する唯一の文字列であることをご存知ですか?その場合は、次のように単純化してみてください。

find . -name "*.php" -exec sed -i 's/?php.*strtolower.*qhroczocgv.*boxknervrr.*-1; ?>//g' {} \;

php、任意の数の異なる文字、strtolower、任意の数のその他の文字、qhrozocgv、任意の数のその他の文字、boxknervrr、任意の数のその他の文字を含む文字列を探します。を押してから、行全体を削除します。

また、このfindセクションでは.もちろん現在のディレクトリを表しますが、希望のディレクトリに切り替えることができます。

関連情報