다음 스크립트가 있습니다.
#!/usr/bin/env bash
# Script to generate MD5 hash for each line.
[ $# -eq 0 ] && { echo "Usage: $0 file"; exit 1; }
file=$1
shopt -s expand_aliases
alias calc_md5='while read -r line; do md5sum <<<$line; done'
paste <(sort "$file" | uniq | calc_md5) <(sort "$file" | uniq)
times
각 줄의 MD5 체크섬을 나란히 인쇄하는데, 이것이 바로 나에게 필요한 것입니다. 예를 들어:
$ ./md5_lines.sh file.dat
5c2ce561e1e263695dbd267271b86fb8 - line 1
83e7cfc83e3d1f45a48d6a2d32b84d69 - line 2
0f2d633163ca585e5fc47a510e60f1ff - line 3
73bb3632fc91e9d1e1f7f0659da7ec5c - line 4
위 스크립트의 문제점은 각 열/스트림에 대해 파일을 두 번 읽고 구문 분석해야 한다는 것입니다. 이상적으로는 모든 행을 정렬하여 고유하게 만들고 한 번만 입력으로 사용하고 싶습니다.
sort
파일을 한 번만( & uniq
) 구문 분석한 다음 출력을 두 개의 다른 스트림으로 리디렉션하고 줄을 나란히 표시하여 더 큰 파일을 더 빠르게 처리할 수 있도록 위 스크립트를 변환하려면 어떻게 해야 합니까 ?
내 또 다른 시도는 다음과 같습니다.
tee >(calc_md5) >(cat -) \
< <(sort "$file" | uniq) \
>/dev/null
times
하지만 스트림을 개별적으로 인쇄합니다(나란히 인쇄하지 않음).
paste
이상적으로는 다음과 같은 방식으로 사용하고 싶지만 tee
오류가 발생합니다.
$ paste >(cat -) >(cat -) </etc/hosts
paste: /dev/fd/63: Permission denied
답변1
두 가지 항목을 나란히 표시하려면 printf를 사용하여 형식화된 인쇄를 수행할 수 있습니다.
#!/bin/bash
sort "$1" | uniq | while read line; do
md5=$(md5sum <<< "$line")
printf "%s %s\n" "$md5" "$line"
done
times
답변2
여러 Perl 메소드:
Perl을 사용하여 md5sum 얻기
$ perl -ne 'BEGIN{ use Digest::MD5 qw(md5_hex) } $k{$_}=md5_hex("$_"); END{ print "$k{$_} - $_" for sort keys(%k) }' file 5c2ce561e1e263695dbd267271b86fb8 - line 1 83e7cfc83e3d1f45a48d6a2d32b84d69 - line 2 0f2d633163ca585e5fc47a510e60f1ff - line 3 73bb3632fc91e9d1e1f7f0659da7ec5c - line 4 d82912361d84a675530f5e32aa6eeda1 - line 5
예, 한 줄짜리입니다.
perl -ne 'BEGIN{use Digest::MD5 qw(md5_hex)} $k{$_}=md5_hex("$_"); END{print "$k{$_} - $_" for sort keys(%k)}' file
이것은 아마도많은쉘에서 이러한 처리를 수행하는 것보다 빠릅니다.
시스템 호출 사용
$ perl -lne 'chomp($md=`md5sum <<<"$_"`); print "$md $_" if !$seen{$_}++' file 83e7cfc83e3d1f45a48d6a2d32b84d69 - line 2 0f2d633163ca585e5fc47a510e60f1ff - line 3 d82912361d84a675530f5e32aa6eeda1 - line 5 73bb3632fc91e9d1e1f7f0659da7ec5c - line 4 5c2ce561e1e263695dbd267271b86fb8 - line 1
답변3
루프 수행과 관련하여 while read
언급된 문제가 많이 있습니다.쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?
여기서는 다음을 사용합니다 perl
.
sort -u < "$file" | perl -MDigest::MD5=md5_hex -lpe '
$_ = md5_hex($_) . " - " . $_'
보다 일반적인 질문이 다음과 중복되거나 변형된 것 같습니다.tee + cat: 출력을 여러 번 사용한 다음 결과를 연결합니다.
두 행이 동일하게 정렬되기 때문에(즉, sort -u
한 행만 유지됨) 동일하며 동일한 MD5 체크섬을 갖습니다. LC_ALL=C sort -u
바이트 간 비교를 기반으로 순서 및 고유성을 사용할 수 있습니다 strcoll()
. 또한 일부 구현 에서는 너무 긴 줄, 종료되지 않은 줄 또는 NUL 문자가 포함된 줄이 sort
포함된 텍스트가 아닌 입력을 차단할 수도 있습니다 .C