16진수 목록이 있습니다. 순서가 맞는지 확인하고 싶습니다. 즉, 오름차순으로 연속된 숫자여야 합니다. 즉, 각 행에서 다음 행까지의 증분은 1이어야 합니다.
16진수 목록의 예:
85AF
85B0
85B1
85B2
85B3
85B4
85B5
85B6
85B7
85B8
85B9
85BA
85BB
85BC
85BD
85BE
85BF
85C0
사실 확인해야 할 숫자가 500개가 넘습니다.
원하는 출력:
All numbers are in sequence
(or)
Numbers are not in sequence.
이것은 ksh를 사용하는 Solaris에서입니다.
답변1
출력이 10진수인 경우 awk는 이를 쉽게 수행할 수 있지만 16진수 숫자를 구문 분석할 수는 없습니다(적어도 표준 awk는 할 수 없고 GNU awk와 같은 일부 버전은 할 수 있음). bc
변환하여 사용하시면 됩니다 . 이는 모든 POSIX 시스템에 적용됩니다.
{ echo "ibase=16"; cat input.txt; } | bc |
awk 'NR==1 {origin = $0-1}
$0!=origin+NR {print "Out-of-sequence number at line", NR; exit(1)}' >&2
답변2
다른 답변에서 언급했듯이 awk에서 이 작업을 수행하는 것은 좋지만 고대 awk(아마도 Solaris에서 사용 가능)는 16진수를 이해하지 못합니다.
빠른 해결책은 wc -l
ksh 수학을 사용하는 것입니다.
#! /bin/ksh
first="0x$(head -n1 infile)"
last="0x$(tail -n1 infile)"
lines=$(wc -l <infile)
if [[ "$(( last - first + 1 - lines ))" -eq 0 ]]; then
echo "All numbers are in sequence."
else
echo "Numbers are not in sequence."
fi
답변3
다음은 한 가지 옵션입니다.
while read x; do echo $((16#$x)); done <yourfile | awk 's && $1!=s+1{exit(1)}{s=$1}'
이 셸 명령은 종료 상태 1(실패 시)과 0(성공 시)을 생성합니다. 이 명령은 아래와 같이 if 절에서 사용하여 원하는 출력을 생성할 수 있습니다.
if while read x; do echo $((16#$x)); done < yourfile | awk 's && $1!=s+1{exit(1)}{s=$1}'
then echo All numbers are in sequence
else echo Numbers are not in sequence
fi
("yourfile"이라는 이름을 일련의 16진수 숫자가 포함된 파일 이름으로 바꿔야 합니다.)
쉘 루프를 생략하고 GNU awk
옵션을 사용하여 -n
16진수를 직접 처리할 수도 있습니다.
if sed 's/^/0x/' <yourfile | awk -n 's && $1+0!=s+1{exit(1)}{s=$1+0}'
then echo All numbers are in sequence
else echo Numbers are not in sequence.
fi
참고: 여기서 sed는 구문상 예상되는 16진수 형식(선행 포함 0x
)을 생성하는 데 사용됩니다.
답변4
엄격한 시퀀스를 원하는 경우 에탈론 시퀀스를 생성하고 이를 파일과 비교하면 쉽게 수행할 수 있습니다.
[ $(comm --nocheck-order -3 \
<(sed '/\S/!d' file) \
<(printf "%X\n" \
$(seq $((16#$(sed '/./!d;q' file))) \
$((16#$(tac file|sed '/./!d;q')))))) ] &&
echo 'Numbers are not in sequence' ||
echo 'All numbers are in sequence'
모든 숫자가 16진수인지 확인하려면 다음을 수행하세요.
sed '/^[[:xdigit:] ]*$/!{
s/.*/Numbers are not in sequence: &/
q
}
$! d
s/.*/All numbers are in sequence/' hexadecimal_number.list
/^[[:xdigit:] ]*$/
줄에 16진수 기호와 공백만 있는지 확인하세요(또는 비어 있는 줄).!
역방향으로 일치하므로{}
위 기호 이외의 기호가 존재할 때마다 명령이 실행됩니다.s/.*/.../;q
s
Numbers are not in sequence
uit 스크립트의 모든 줄을 인쇄 줄로 바꿉니다.q
$! d
스크립트가 이전 행(패턴 일치)을 실행하지 않고 해당 행이 마지막 행이 아닌 경우d
다음 행부터 시작합니다.s/.*/.../
스크립트가 마지막 줄에 도달하면(모든 줄이 패턴과 일치함) 인쇄하여s
마지막 줄을 바꿉니다.All numbers are in sequence