2016-10-05 11 views
1

ファイルパスがいくつか入っているバイナリファイルがあります。パスが特定の文字列で始まる場合、残りのファイルパス[\x20-\x7f]+はマスクされ、ファイルの一般的な構造とサイズはそのままです。その後バイナリファイルの特定のファイルパスをマスクする

/usr/local/bin/ 
/home/joe/ 

バイナリデータでは、このような出現:検索するパスのリストを持つので

はこれです

^@^@^@^@/home/joe/documents/hello.docx^@^@^@^@ 

は、このように変更します。

^@^@^@^@/home/joe/********************^@^@^@^@ 

これを行うにはどうすればよいですか? sed、perl、awkには方法がありますか?または、文字列を見つけた場所でCまたはPHPプログラムを作成し、strlen()個のマスク文字をその場所に書き込む必要がありますか?

答えて

3

perlは、バイナリデータの処理に適しています。 sedawkについては、GNU実装のみが一般的にバイナリデータに対処でき、もう1つはNULバイトで、または2つの改行文字間の長いシーケンスや非終端ラインで窒息します。あなたは/rフラグのperlのではない、あまりにも古いバージョンを必要とするだろう

perl -pi.back -e 's{(/usr/local/bin|/home/joe)/\K[\x20-\x7f]+}{ 
    $& =~ s/./*/rg}ge' binary-file 

はと\K(変数にそれを適用するのではなく、置換の結果を返します)(マッチした文字列の先頭にリセット)。

デフォルトでは、perl -pは改行文字が[\x20-\x7f]の一部ではないため、一度に1行で動作します。これは問題ありません。

+0

このソリューションは、すぐに使用できました。ログファイルの個人情報の匿名化に最適です。 ( ''ビンの後ろに '/'がありませんが、詳細です!) – forthrin

+0

@forthrin。ありがとうございました、私は今、 '/'を交代から外して、両方のパスに適用するようにしました。 –

0

私はそれが最適化できると確信していますが、ここで動作するいくつかのperlコードです。これはフィルタなので、すべてのstdinを$dataに読み込み、次に配列@dirsの各文字列に対してパターンの代わりを行います。しかし置換は固定された文字列ではなく、代入コマンドの修飾子のために評価されるreplace($dir,$1)という関数呼び出しがあります。e

#!/usr/bin/perl 
use strict; 
sub replace{ 
    my ($dir,$rest) = @_; 
    $rest =~ s/./*/g; 
    return $dir.$rest; 
} 
my @dirs = ('/usr/local/bin/','/home/joe/'); 
my $data = join("",<STDIN>); 
foreach my $dir (@dirs){ 
    $data =~ s|$dir([\x20-\x7f]+)|replace($dir,$1)|ge; 
} 
print $data; 

この関数には、2つの引数、ディレクトリ、パターンの取得部分が与えられます。キャプチャされた文字列内の各文字を置き換えた後、これらを連結して返します。

関連する問題