ファイルを検索し、特定のパターンを対応するハッシュ(SHA1)値に置き換えたいと思います。
たとえば、file.txt
次の内容があります。
one S56G one two three
four five V67X six
[A-Z][0-9]\{2\}[A-Z]
パターンを一致するSHA1値に置き換えたいです。上記の例では、一致はとS56G
ですV67X
。
を使用してsed
次のことを試しました。
sed "s/[A-Z][0-9]\{2\}[A-Z]/$(echo \& | sha1sum)/g"
結果は常にハッシュ値なので成功しません'&'
。
ge
また、次のコマンドタグを試してみました。
sed 's/[A-Z][0-9]\{2\}[A-Z]/echo & | sha1sum/ge'
エラーが発生します。
sh: 1: one: not found
sha1sum: one: No such file or directory
sha1sum: two: No such file or directory
sha1sum: three: No such file or directory
答え1
$(…)
あなたの試みでコマンドの置き換え()を実行してください。今後 sed
実行中で、文字列がパラメータとして渡されます。
コードの実行をサポートするスクリプト言語を置き換えるには、正規表現を使用してください。
perl -MDigest::SHA=sha1_hex -pe 's/[A-Z][0-9]{2}[A-Z]/sha1_hex$&/ge' inputfile
php -R 'echo preg_replace("/[A-Z][0-9]{2}[A-Z]/e","sha1(\$0)",$argn),"\n";' inputfile
ruby -rdigest/sha1 -pe '$_.gsub!(/[A-Z][0-9]{2}[A-Z]/){Digest::SHA1.hexdigest$&}' inputfile
python -c 'import sys,fileinput,re,hashlib;[sys.stdout.write(re.sub("[A-Z][0-9]{2}[A-Z]",lambda s:hashlib.sha1(s.group(0)).hexdigest(),l))for l in fileinput.input()]' inputfile
答え2
@manatoworkが間違いなく答えを提供しました。ただ気になって追加...
bash+sha1sum バリアント。
function fail()
{
printf "Failed on line \`%s'\n" "$line" >&2
exit 2
}
declare -A sha_map;
re='[A-Z][0-9]{2}[A-Z]';
while read -r line; do
while [[ $line =~ $re ]]; do
m="${BASH_REMATCH[0]}";
if ! [[ ${sha_map[$m]} ]]; then
sha="$(printf "%s" "$m" | sha1sum)" || fail;
sha_map["$m"]=${sha%% *};
fi
line=${line//$m/${sha_map[$m]}};
done
printf "%s\n" "$line";
done <"$fn"
答え3
これが私の解決策です。
cp file.txt result.txt
cat file.txt | grep -o '[A-Z][0-9]\{2\}[A-Z]' | while read i ; do
sed -i "s/$i/$(echo -n $i | sha1sum | cut -f 1 -d ' ')/g" result.txt
done
すべての行をコピーして端末に貼り付けます。そしてfile.txt
one S56G one two three
four five V67X six
わかりました。
one 03763566330069a397584344c0a640a3cba05a4c one two three
four five 7802350a2592cdc6dfdee408336919ee9e3cc5f2 six
このソリューションはO(n ^ 2)の複雑さを持ち、パターンマッチごとにターゲットファイルを処理するため、パターンマッチングの多い大容量ファイルには適していません。