특정 문자가 보일 때까지 모든 문자를 바꿉니다.

특정 문자가 보일 때까지 모든 문자를 바꿉니다.

예를 들어, 다음은 md5sum 명령의 출력입니다.

35c9581c469c366e286be708a9d9f939  input.txt

이것은 내가 실행 중인 명령줄입니다.

md5sum input.txt | sed -f script.sed

md5sum의 출력이 다음과 같기를 원합니다.

35c9xxxxxxxxxxxxxxxxxxxxxxxxxxxx  input.txt

현재 내 .sed 스크립트에는 처음 4자를 제외한 모든 내용을 편집하는 다음 내용이 포함되어 있습니다.

s/./x/5g

공백 "" 을 발견하면 이 작업을 중지해야 합니다 . 어떤 아이디어가 있나요?

답변1

if (md5sum) hash; 그러면 이 작업이 수행됩니다(중괄호 확장을 지원하는 쉘에서).

sed -e's/./x/'{5..32} infile

else 첫 번째 문자 공백이 표시될 때까지 모든 문자 길이에 대해 다음을 수행합니다.

sed일반 솔루션으로 , 및 를 사용하십시오 .

sed -E ':a s/^(.{4}x{0,})[^x ]/\1x/;ta' infile
  • :ased우리의 이름이 붙은 태그a
  • s/아래 일치 항목을 교체하세요.
    • ^행 앵커 포인트의 시작입니다.
    • (조별 예선 시작
      • .단일 문자 일치
      • .{4}4개 문자(또는 ....)만 일치하고 뒤에 오는 문자와 일치합니다.
      • x{0,}0자 이상 x(또는 x*)
    • )그룹 매치가 종료되고 역방향 참조는\1
    • [^x ]strings 를 제외한 모든 문자와 일치합니다 x. (문자 클래스에서 해당 ^문자가 열린 직후 첫 번째 문자인 경우 부정 일치가 이루어집니다.)[[^...]
  • /아래와 함께
    • \1는 위에서 일치하는 부분에 대한 역참조 (...)이므로 첫 번째 부분이 다시 제자리에 있지만 x나중에 추가 콘텐츠가 추가됩니다.
    • 그리고 하나 , 위에서 우리가 조별 예선에서 득점 x하지 못했다는 사실을 기억하시나요 ? 이제 하나씩 교체할 캐릭터들 입니다 .[^x ](...)x
  • /교체 종료
  • ;새 명령 시작
  • taa교체가 성공하면 레이블로 이동합니다. 그렇지 않으면 모든 문자를 다음으로 교체했으며 이제 교체하고 명령을 x종료할 문자가 남아 있지 않음을 의미합니다.sed

답변2

md5sum해시에 대해 항상 32자의 출력을 생성합니다. 공백을 검색하는 대신 32자를 찾은 다음 공백을 찾은 다음 마지막 28자를 X로 바꿀 수 있습니다.

md5sum input.txt | sed -E 's/^([[:xdigit:]]{4})[[:xdigit:]]{28} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /'
35c9xxxxxxxxxxxxxxxxxxxxxxxxxxxx  input.txt

분해 설명:

's/^([[:xdigit:]]{4})[[:xdigit:]]{28} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /'

's/A                                  / B                             /'
we're substituting patterns matching A with B

's/  [[:xdigit:]]    [[:xdigit:]]     /                               /'
we're looking for two groups of hexadecimal characters

's/  [[:xdigit:]]{4} [[:xdigit:]]{28} /                               /'
The first group has exactly four characters
The second group has exactly twenty-eight characters

's/ ([[:xdigit:]]{4})[[:xdigit:]]{28} /                               /'
The first group is a "capture group" which we can reference later

's/ ([[:xdigit:]]{4})[[:xdigit:]]{28} /\1                             /'
We will print out the first group verbatim in the output

's/ ([[:xdigit:]]{4})[[:xdigit:]]{28} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /'
We will print x's followed by a space for the next 28 characters

's/^([[:xdigit:]]{4})[[:xdigit:]]{28} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /'
The statement must appear at the start of a line and have a space at the end.

답변3

펄 방법:

$ md5sum file | perl -ple 's/^(.{4})(\S+)(\s+.*)/$1 . "x" x length($2) . $3/e'
9191xxxxxxxxxxxxxxxxxxxxxxxxxxxx  file

처음 4개 문자( ^(.{4}))를 찾은 다음 공백이 아닌 문자를 가능한 한 많이( (\S+)), 첫 번째 이상의 공백을 찾은 다음 줄 끝까지 모든 항목( (\s+.*))을 찾습니다. 그런 다음 첫 번째 캡처된 값( $1, 처음 4자) 으로 대체되고 , 이는 x두 번째 캡처된 그룹( )의 길이만큼 반복되고 "x" x length($2), 마지막 캡처된 그룹이 이어집니다 $3. /e를 계산하려면 연산자 끝에 대체가 필요합니다 s///.

md5sum물론, 항상 실행되므로 해시 길이(4)가 항상 28이 된다는 것을 안다면 다음과 같이 단순화할 수 있습니다.

$ md5sum file | perl -ple 's/^(.{4})(\S+)/$1 . "x" x 28/e'
9191xxxxxxxxxxxxxxxxxxxxxxxxxxxx  file

심지어:

$ md5sum file | perl -ple 's/(?<=.{4})(\S+)/"x" x 28/e'
9191xxxxxxxxxxxxxxxxxxxxxxxxxxxx  file

답변4

$ md5sum somefile
d68610fdffd770de94818268899d6abb  somefile
$ md5sum somefile | { read -r hash pathname; printf '%.4sxxxxxxxxxxxxxxxxxxxxxxxxxxxx  %s\n' "$hash" "$pathname" }
d686xxxxxxxxxxxxxxxxxxxxxxxxxxxx  somefile

이는 해시와 경로 이름을 두 개의 쉘 변수로 읽은 다음 이를 인쇄하여 해시의 마지막 28자를 대체합니다 x.

여러 파일을 지원하려면 루프를 사용하세요.

$ md5sum somefile* | while read -r hash pathname; do printf '%.4sxxxxxxxxxxxxxxxxxxxxxxxxxxxx  %s\n' "$hash" "$pathname"; done
d41dxxxxxxxxxxxxxxxxxxxxxxxxxxxx  somefile
d686xxxxxxxxxxxxxxxxxxxxxxxxxxxx  somefile1
d41dxxxxxxxxxxxxxxxxxxxxxxxxxxxx  somefile2

관련 정보