파이프를 통해 첫 번째 필드를 10진수에서 16진수로 변환하는 방법

파이프를 통해 첫 번째 필드를 10진수에서 16진수로 변환하는 방법

다음과 같은 화면 출력이 있습니다.

170.170.170.0.156.96 24

파이프하고 다음 형식으로 변환하고 싶습니다

b8:27:eb:ef:3b:4a 24

기본적으로 첫 번째 필드를 10진수에서 16진수로 변환하며 점은 콜론으로 대체됩니다. 어떤 제안이 있으십니까?

답변1

$ cat input
170.170.170.0.156.96 24
$ perl -lane '$F[0] =~ s/(\d+)/sprintf "%02x",$1/eg; $F[0] =~ tr/./:/; print "@F"' < input
aa:aa:aa:00:9c:60 24
$ 

인쇄하지 않고 표준 입력을 반복하고 로 분할하여 @F첫 번째 열( $F[0])을 삭제하고 모든 숫자를 해당하는 16진수와 .to: tr변환으로 바꿉니다. print 에 포함된 새 값입니다 @F.

답변2

Python방법:

--모듈 사용 re:

python -c 'import sys,re;
print(re.sub(r"\d+(?!$)", lambda m: "{:x}".format(int(m.group())), 
sys.stdin.read().strip()))' <inputfile

-- split()++ map()체인 사용 join():

python -c 'import sys; parts=sys.stdin.read().strip().split(); 
print(".".join(map(lambda n: "{:x}".format(int(n)), parts[0].split("."))) 
 + " " + parts[1])' <inputfile

출력(두 방법 모두):

aa.aa.aa.0.9c.60 24

답변3

awk레코드 구분 기호로 점을 사용 하고 처리합니다.

echo '170.170.170.0.156.96 24' |
awk -v RS='.' '{ s = (s ? s ":" : "" ) sprintf("%02x", $0) } END { print s }'

여기서 결과 문자열은 를 s사용하여 10진수를 16진수로 변환하여 생성됩니다 sprintf(). 입력이 완료되면 결과를 인쇄합니다.

10진수에서 16진수로의 변환에서는 후행이 24삭제되므로 명시적으로 처리할 필요가 없습니다.

위 파이프의 결과는 string 입니다 aa:aa:aa:00:9c:60.

답변4

IFSIP 주소 부분을 처리하기 위해 서브셸의 토큰화(따옴표 없음 $var)와 printf형식 문자열에 맞게 가변 길이 인수를 처리하는 기능을 활용할 수 있습니다 .

$ ( IFS='.';var='170.170.170.0.156.96';new=$(printf '%02x:' $var); echo ${new:0:${#new}-1} )
aa:aa:aa:00:9c:60

${new:0:${#new}-1}맹목적 으로 :추가된 마지막 문자 가 printf.

170.170.170.0.156.96 24단일 입력 문자열로 올 수 있다는 점을 고려하면 stdin두 문자열을 모두 변수로 읽어서 별도로 처리할 수 있습니다.

$ echo "170.170.170.0.156.96 24" | while read ip num ;  do
> hex=$( IFS='.';new=$(printf '%02x:' $ip); echo ${new:0:${#new}-1} );  
> printf '%s %d\n' "$hex" "$num"; done
aa:aa:aa:00:9c:60 24

나중에 스크립트에서 출력도 필요한 경우 결과 값을 명명된 파이프에 쓰거나, 동일한 하위 셸에서 계속 작업하거나, 프로세스 대체를 사용하는 것을 고려하세요. 바라보다이것더 많은 정보를 알고 싶습니다.

관련 정보