일련의 숫자에서 누락된 숫자 검색

일련의 숫자에서 누락된 숫자 검색

그래서 저는 많은 정보를 포함하는 파일을 가지고 있으며, 정보의 각 "덩어리"에는 다음과 같은 고유한 식별자가 있습니다.

"색인":숫자

Linux에서 다음 명령을 사용한 후:

$ cat file | grep index

나는 다음과 같은 결과를 얻습니다.

"index": 1
"index": 2
"index": 3
...
"index": 10001

그 사이에는 연속 형식의 일련의 숫자가 있습니다.

거기 어딘가에 숫자가 빠져 있는데 그 숫자를 알아내려고 노력 중이에요.

나는 여러 가지를 시도했지만 그 중 아무것도 작동하지 않았습니다. 추가할 수 있는 다른 명령이 있습니까? 아니면 누락된 색인 표시를 검색하는 더 좋은 방법이 있습니까?

답변1

이 명령을 사용하여 diff파일과 N에서 M까지의 일련의 숫자 간의 차이를 확인할 수 있습니다. 이 awk명령은 텍스트를 구문 분석하고 숫자만 가져오는 데 사용됩니다.

diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 10001) | awk '{print $2}'

위의 코드는 1파일 번호를 의 시퀀스와 비교합니다 10001.

이상기능의이를 구현하는 방법은 파일의 마지막 번호(10001)를 감지하고 이를 변수에 할당하는 것입니다.

max=$(tail -1 file.txt | awk '{print $2}')
diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 $max) | awk '{print $2}'

예를 들면 다음과 같습니다.

파일.txt:

"index": 1
"index": 5
"index": 8
"index": 9
"index": 10
"index": 12
"index": 13
"index": 15
max=$(tail -1 file.txt | awk '{print $2}')
diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 $max) | awk '{print $2}'

산출:

2
3
4
6
7
11
14

그런데 누락된 값을 이 형식으로 인쇄하려면 마지막 명령문을 다음과 같이 "index": the_missing_number변경할 수 있습니다 .awk print

diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 $max) | awk '{print "\"index\": "$2}'

답변2

귀하의 예에서 색인 레이블과 정수를 포함하는 파일에 대한 두 가지 중요한 가정은 다음과 같습니다.

"index": 1
"index": 2
"index": 3
...
"index": 10001

가정은 다음과 같습니다.

  1. 첫 번째 행부터 마지막 ​​행까지 읽을 때 인덱스 정수는 오름차순으로 정렬됩니다.
  2. 하나 이상의 공백이나 탭은 "index":레이블을 색인 정수와 구분합니다.

이 작은 루프는 둘 다 참인 한 bash누락된 숫자를 출력할 수 있습니다 (그러나 코드 뒤의 경고를 읽으십시오). 인덱스 레이블과 정수가 있는 파일의 이름은 다음과 같습니다 indexes.txt.

cur_idx=0
last_idx=0
while read label cur_idx; do
  (( last_idx != ( cur_idx - 1 ))) && echo $(( cur_idx - 1 ))
  last_idx=${cur_idx}
done < indexes.txt

루프는 표시된 마지막 인덱스를 기억하고 새 인덱스 행을 읽은 후 현재(새) 인덱스[마이너스 1]를 마지막 인덱스와 비교합니다. 동일하지 않으면 인덱스를 건너뛰고 건너뛴 인덱스를 인쇄합니다.

경고하다:

두 개 이상의 연속 누락 인덱스가 있는 경우 이 루프는 첫 번째 누락 인덱스만 인쇄합니다. 모든 내용이 인쇄되지는 않습니다.
즉, 다음과 같은 경우입니다.

"index": 21
"index": 24

( 22sum 누락 23) 루프는 을 인쇄합니다 22. 그러나 이렇게 하면 indexes.txt나중에 파일을 보고 21건너뛴 숫자 수를 확인할 수 있습니다. 귀하의 질문에서 제가 받은 인상은 누락된 인덱스가 한두 개뿐이므로 이것이 귀하를 방해해서는 안 된다는 것입니다.

답변3

간단한 grep/awk 문을 사용하여 이를 수행할 수 있습니다. awk 줄 번호(NR)와 동일한 번호가 없는 첫 번째 줄의 인덱스를 일치시킨 다음 줄 번호를 인쇄하고 종료합니다.

grep index file | awk -F: '{ if (NR != $2 ) {print "missing " NR; exit;} }'

답변4

사용행복하다(이전 Perl_6)

~$ raku -e 'my @a; for lines() {@a.push: $/.Int if .match(/<?after \"index\"\: \s > \d+ /) };  \
            put ((1..10) (-) @a.Set).keys.sort;'  index.txt

#OR

~$ raku -e 'my @a; for lines() {@a.push: $0.Int if .match(/<?after \"index\"\: \s > (\d+) /) };  \
            put ((1..10) (-) @a.Set).keys.sort;'  index.txt

Raku는 Perl 계열의 프로그래밍 언어입니다. 2015년에 Perl_6으로 출시되었고 2019년에 Raku로 이름이 변경되었습니다. 따라서 Raku에서는 "Perl주의"를 많이 발견할 수 있습니다.

Raku의 흥미로운 기능 중 하나는 집합 의미론입니다. 유니코드 및 ASCII 연산자를 모두 사용할 수 있습니다. 위 코드에서 ASCII (-)차이 설정(비대칭). 유니코드를 사용할 수도 있습니다.


SET MINUS
Unicode: U+2216, UTF-8: E2 88 96

입력 예(최대값은 100임):

"index": 1
"index": 2
"index": 3
"index": 5
"index": 100

샘플 출력(두 가지 코드 예):

4 6 7 8 9 10

경고: 대칭 및 비대칭 Set 연산을 혼동하기 쉽습니다. 예를 들어 위 코드의 경우 컬렉션의 순서를 반대로 해서 ASCII (^)나 유니코드를 시도해 보면 대칭 세트 차이대신에 큰 차이점이 보입니다( 1..99테스트 범위로 사용됨).

~$ cat index.txt | perl6 -e 'my @a = do for lines() {$/.Int if .match(/<?after \"index\"\: \s > \d+ /) }; put (@a.Set (-) (1..99)).keys.sort;'
100
~$ cat index.txt | perl6 -e 'my @a = do for lines() {$/.Int if .match(/<?after \"index\"\: \s > \d+ /) }; put (@a.Set (^) (1..99)).keys.sort;'
4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

https://docs.raku.org/언어/setbagmix
https://raku.org

관련 정보