처음 4자를 제외한 모든 문자 바꾸기

처음 4자를 제외한 모든 문자 바꾸기

다음과 같이 sed에 명령을 입력하고 싶습니다.

md5sum input.txt | sed 's/^\(....\).*/\1/;q'

이는 체크섬의 처음 4개 문자만 출력하여 수행됩니다. 하지만 처음 4자를 출력하고 싶지만 다른 모든 문자(편집 정보) 대신 x를 사용하고 싶습니다. 나는 지금 매우 길을 잃었습니다.

답변1

GNU Sed를 사용하면,

md5sum input.txt | sed 's/./x/5g'

이는 대체 문자열의 처음 4자를 건너뛰고 다른 모든 문자를 대체합니다.

Awk에 대한 POSIX 대안(더 간단한 것이 있을 수 있음)

md5sum xad | awk '{
  four=substr($0, 1, 4)
  rest=substr($0, 5)
  gsub(/./, "x", rest)
  print four, rest
}' OFS=""

답변2

POSIXly에서는 sed 루프를 사용하여 x4자 접두사 뒤의 첫 번째 비문자를 반복적으로 바꿀 수 있습니다.

$ md5sum input.txt | sed '
:a
s/^\(....x*\)[^x]/\1x/
ta
'

첫 번째 필드(체크섬)만 바꾸려면 [^x]로 바꾸세요.[^x ]

답변3

perl사용할 수 없는 경우 GNU sed:

md5sum input.txt | perl -pe 's/^.{4}(*SKIP)(*F)|./x/g'

^.{4}(*SKIP)(*F)처음 네 문자가 대체되는 것을 방지합니다.

|.교체해야 하는 대체 패턴을 지정합니다.


체크섬만 변경하십시오.

md5sum ip.txt | perl -pe 's/(^.{4}|\h.*$)(*SKIP)(*F)|./x/g'

md5sum출력이 a로 시작하는 경우 \(예: 파일 이름에 개행 문자가 있는 경우) 대신 를 사용하여 ^\\?.{4}처음 ^.{4}5개 문자의 마스크를 해제할 수 있습니다.

답변4

Quasímodo의 답변의 문제점은 x파일 이름도 's.'로 대체한다는 것입니다. OP는 이에 대한 후속 질문을 게시했습니다. sed우주에서 멈추는 솔루션은 다음과 같습니다 .

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

md5sum input.txt | sed 's/^\([a-zA-Z0-9]\{4\}\)[a-zA-Z0-9]\{28\} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /g'
35c9xxxxxxxxxxxxxxxxxxxxxxxxxxxx  input.txt

분해 설명:

's/^\([a-zA-Z0-9]\{4\}\)[a-zA-Z0-9]\{28\} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /g'

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

's/   [a-zA-Z0-9]       [a-zA-Z0-9]       /                               /g'
we're looking for two groups of alphanumeric  characters

's/   [a-zA-Z0-9]\{4\}  [a-zA-Z0-9]\{28\} /                               /g'
The first group has exactly four characters
The second group has exactly twenty-eight characters

's/ \([a-zA-Z0-9]\{4\}\)[a-zA-Z0-9]\{28\} /                               /g'
The first group is a "capture group" which we can reference later

's/ \([a-zA-Z0-9]\{4\}\)[a-zA-Z0-9]\{28\} /\1                             /g'
We will print out the first group verbatim in the output

's/ \([a-zA-Z0-9]\{4\}\)[a-zA-Z0-9]\{28\} /\1xxxxxxxxxxxxxxxxxxxxxxxxxxxx /g'
We will print x's followed by a space for the next 28 characters

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

관련 정보