크기가 3GB이고 잘못된 json인 users.json이라는 파일이 있습니다. 그래서 내가 원하는 것은 파일의 텍스트 내용을 읽고 파일에 포함된 사용자 이름인 필요한 정보를 얻은 다음 중복이 없는 한 줄에 1개의 사용자 이름을 포함해야 하는 usernames.txt 파일에 쓰는 것입니다.
json 파일의 사용자 이름 형식은 "username":"someUsername"입니다.
모든 사용자 이름을 수집하여 텍스트 파일에 넣고 중복이 없는지 어떻게 확인합니까?
Node.js와 PHP로 시도해 보았지만 아직 아무 것도 작동하지 않았습니다. bash를 사용하여 멋진 작업을 수행할 수 있기를 바랍니다.
파일에 포함된 데이터의 예(이미 형식을 언급했기 때문에 그다지 도움이 되지 않을 수도 있음 "username":"someUsername"
):
username":"satish_nanded","original_ff_id":"99554"},"100003":{"username":"sweetnamu","original_ff_id":"100003"}},"08fdlhNuZEM1z8q4mQftYUtO7uC3":{"575511":{"username":"lrlgrdnr","original_ff_id":"575511"}},"08fe4Dg7NeOTItq3b9Pi8ORsX5J2":{"59520":{"username":"joneljon","original_ff_id":"59520"}},"08gsZHsbm9Rew4S2IqcbGvD9Fct1":{"724707":{"username":"jacksonc4565","original_ff_id":"724707"}
답변1
이 grep
명령을 사용하여 원하는 패턴을 일치시키고 sort
중복 항목을 필터링할 수 있습니다. 입력 파일이 다음 input.json
과 같을 경우 출력은 다음과 같습니다 usernames.txt
.
grep -P -o '(?<="username":")[^"]*' input.json | sort -u > usernames.txt
그것을 파괴:
grep
파일의 정규식을 일치시키는 명령줄 유틸리티입니다. 정규식은 찾고자 하는 텍스트를 설명하는 효율적인 방법입니다.-P
grep
"Perl 호환 정규 표현식"을 사용하도록 알려주십시오 . grep의 매뉴얼 페이지에서는 이를 "매우 실험적"이라고 설명합니다!-o
grep
일치하는 텍스트만 출력하도록 지시합니다 . 기본적으로grep
일치하는 항목이 발견될 때마다 일반적으로 전체 줄이 출력됩니다.'(?<="username":")[^"]*'
정규식 자체입니다.'....'
명령줄 셸이 그 안에 있는 내용을 해석하지 못하도록 작은따옴표로 묶었습니다.(?<=...)
이것은 ... 불리운다역방향 주장. 다른 것보다 먼저 일치시키고 싶지만"username":"
출력에는 포함시키지 않기를 원한다고 나와 있습니다.[^"]*
"가 아닌 가능한 한 많은 문자를 의미합니다"
. 다시 세분화할 수 있습니다.[..]
캐릭터 클래스입니다. 현재는 대괄호 사이의 모든 문자가 허용됩니다. 하지 않는 한...^"
^
캐럿을 문자 클래스의 첫 번째 문자로 사용하면 이는 다음을 의미합니다.아니요다음 문자 중 하나*
[^"]
0개 이상의 이전 항목(이 경우 전체)을 나타냅니다.
파이핑을 통해 sort
사용자 이름을 알파벳순으로 정렬합니다 . 옵션은 -u
"고유한 항목만", 즉 중복 항목이 없음을 의미합니다.
참고: 이 모든 것은 우리가 일치하는 패턴이 파일의 다른 곳에 나타나지 않거나(가능성이 낮음) JSON 자체의 손상으로 인해 일치가 실패하지 않는다고 가정합니다(그럴 수도 있음). 파일이 어떤 방식으로 손상되어 끝나는지 확실하지 않습니다.)
편집하다:
줄이 너무 길다는 불만이 자주 있고 grep
어떤 이유로 sed -e 's/,/,\n/'
실제로 작동하지 않기 때문에 이 split
명령은 파일을 보다 관리하기 쉬운 덩어리로 나누는 데 사용됩니다.
답변2
깨지는 매우 긴 JSON 레코드가 있는 것 같습니다 grep -P
. 대체 솔루션은 다음과 같습니다.
grep -o '"username":"[^"]*' users.json \
| cut -d '"' -f 4 \
| uniq \
| sort -u \
> usernames.txt
여기에서 grep
전체 "사용자 이름:값" 필드를 추출하고 cut
값을 추출한 후 uniq | sort -u
사용자 이름을 고유하게 만듭니다.
uniq
필요 없음. 3GB 파일의 경우 연속된 중복이 많은 수백만 개의 이름 목록을 얻고 싶습니다. 쓸모없어 보이는 것은 작업의 부담을 uniq |
덜어주고 작업을 더 빠르게 진행하게 할 수 있습니다. sort
그렇지 않으면 아프지 않을 텐데