그래서 저는 많은 정보를 포함하는 파일을 가지고 있으며, 정보의 각 "덩어리"에는 다음과 같은 고유한 식별자가 있습니다.
"색인":숫자
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
가정은 다음과 같습니다.
- 첫 번째 행부터 마지막 행까지 읽을 때 인덱스 정수는 오름차순으로 정렬됩니다.
- 하나 이상의 공백이나 탭은
"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
( 22
sum 누락 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