파일을 검색하고 특정 패턴을 해당 해시(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)의 복잡성을 가지며 각 패턴 일치에 대해 대상 파일을 처리하므로 패턴 일치가 많은 대용량 파일에는 적합하지 않습니다.