이 SE 데이터 쿼리 의 .csv
출력을 다음 과 같이 출력 하고 있습니다 (5022 항목 만 해당).
"{
""id"": 281952,
""title"": ""Flash 11.2 No Longer Supported by Google Play""
}"
"{
""id"": 281993,
""title"": ""Netbeans won't open in Ubuntu""
}"
(그리고 ^M
[number]와 “”title “”사이에 줄 끝이 있습니다). 다음과 같이 표시해야합니다.
281952,Flash 11.2 No Longer Supported by Google Play
281993,Netbeans won't open in Ubuntu
나는 이것을 꽤 쉽게 이름이 남지 않는 특정 텍스트 편집기에서 수정했지만 쿼리를 새로 고칠 때마다 다시 할 필요가 없도록 다른 스크립트를 사용할 수 있도록 스크립트를 만들고 싶었습니다. 나는 사용했다 sed
…
이 일련의 명령은 완벽하게 작동합니다 (비효율적이지만 시행 착오 솔루션 일뿐입니다).
# Print the ^M and remove them, write to a new file:
cat -v QueryR* | sed 's/\^M//' > QueryNew
# remove all the other junk:
sed -i 's/{//' QueryNew
sed -i 's/}//' QueryNew
sed -i 's/""//g' QueryNew
sed -i 's/^"//' QueryNew
sed -i '/,/{N;/\n.*title:\s/{s/,\n.*title:\s/,\ /}}' QueryNew
sed -i 's/^\s\+//' QueryNew
sed -i '/^\s*$/d' QueryNew
sed -i 's/^id:\ //' QueryNew
sed -i 's/,\ /,/' QueryNew
sed -i 's/\\//g' QueryNew
그렇다면 왜 그렇지 않습니까? ^M
and 만 {}
제거하면 나머지는 여전히 존재합니다.
#!/bin/bash
cat -v QueryR* | sed 's/\^M//' > QueryNew
sed -i '{
s/{//
s/}//
s/""//g
s/^"//
/,/{N;/\n.*title:\s/{s/,\n.*title:\s/,\ /}}
s/^\s\+//
/^\s*$/d
s/^id:\ //
s/,\ /,/
s/\\//g
}' QueryNew
내 실수가 정말 분명하다고 확신합니다 …
답변
사용 cat -v
문자에 CR 문자를 설정하는 ^M
시퀀스 것은 나에게 근본적으로 추한 것 – 당신이 DOS 라인 엔딩 사용을 제거해야하는 경우 dos2unix
, tr
또는 sed 's/\r$//
‘
sed를 사용한다고 주장하면 원하지 않는 모든 임의의 비트를 삭제하지 않고 원하는 비트를 인쇄하는 것이 좋습니다.
$ sed -rn -e 's/\"//g' -e 's/(.*): (.*)\r/\2/p' QueryR | paste -d '' - -
281952,Flash 11.2 No Longer Supported by Google Play
281993,Netbeans won't open in Ubuntu
값 시퀀스의 각 끝에서 0 개 이상의 따옴표를 일치시켜 따옴표를 제거하여 키-값 추출로 롤백 할 수 있습니다.
$ sed -rn 's/(.*): \"*([^"]*)\"*\r/\2/p' QueryR | paste -d '' - -
281952,Flash 11.2 No Longer Supported by Google Play
281993,Netbeans won't open in Ubuntu
당신이 얻을 수있는 정말 멋진을하고 에뮬레이션 paste
에서 sed
처음에 라인 쌍을 결합하여 ,\r$
종료 한 후 다중 키 – 값 쌍을 일치 ( g
) 및 비 탐욕
$ sed -rn '/,\r$/ {N; s/([^:]*): \"*([^:"]*)\"*\r\n?/\2/gp}' QueryR
281952,Flash 11.2 No Longer Supported by Google Play
281993,Netbeans won't open in Ubuntu
(개인적으로 KISS 접근 방식을 선호하고 첫 번째 접근 방식을 사용합니다).
FWIW, 입력이 초과 인용 된 것으로 보이므로 적절한 JSON 파서를 설치하는 것이 좋습니다. jq
sudo apt-get install jq
그런 다음 같은 것을 할 수 있습니다
$ sed -e 's/["]["]/"/g' -e 's/"{/{/' -e 's/}"/}/' QueryR | jq '.id, .title' | paste -d, - -
281952,"Flash 11.2 No Longer Supported by Google Play"
281993,"Netbeans won't open in Ubuntu"
불필요한 따옴표를 제거한 다음 jq
관심있는 필드를 추출하는 데 사용 jq
합니다. DOS 스타일 줄 끝을 처리 하는 것으로 보이므로 제거하기 위해 특별한 단계를 수행 할 필요가 없습니다.
jq '.[]'
모든 속성 값 쌍을 덤프 하도록 변경하십시오 .
grep -o를 사용하여 줄 바꿈 극복jq
에서
얻은 영감과 기본 구문에 대한 크레딧
답변
나는 스틸 드라이버 및 추가 땜질 덕분에 고쳤습니다. 정제되지 않았지만 작동합니다.
sed '{
s/"{//
s/}"//
s/^"//
/,\r/{N;/\n.*title.*:\s/{s/,\r\n.*title.*:\s/,/}}
s/""//g
s/^\s\+//
/^\s*$/d
s/^id:\ //
s/\\//g
}' QueryR* | tee "$1"
번역 :
s/"{//
제거 "{
s/}"//
제거 }"
s/^"//
제거 "
라인의 시작부터
/,\r/{N;/\n.*title.*:\s/{s/,\r\n.*title.*:\s/,\ /}}
경기를 ,\r
한 줄에와 [whatever]title[whatever]:
다음 라인은, 함께하는 모든 교체 ,
s/""//g
남아있는 모든 이중 따옴표를 제거
s/^\s\+//
라인의 시작부터 제거 공백을
/^\s*$/d
빈 줄이 제거
s/^id:\ //
제거 id:
는 후 공간
s/\\//g
백 슬래시를 제거하기위한 (이스케이프 문자를 “(일부 제목 필드에 추가됨)
tee "$1"
스크립트를 실행할 때 출력 파일을 지정하십시오 (예 :./queryclean newquery.csv
답변
질문은을 요구하지만 sed
Python과 함께 sed의 문제를 해결할 수 있습니다.
from __future__ import print_function
import sys
with open(sys.argv[1]) as f:
for line in f:
if '""id""' in line:
print(line.strip().split(':')[1],end="")
if '""title""' in line:
title = " ".join(line.strip().split(':')[1:])
print(title.replace('""'," "))
이 코드는 python2 및 python3 모두와 호환되므로 어느 쪽이든 작동합니다.
샘플 실행 :
bash-4.3$ cat questions.txt
"{
""id"": 281952,
""title"": ""Flash 11.2 No Longer Supported by Google Play""
}"
"{
""id"": 281993,
""title"": ""Netbeans won't open in Ubuntu""
}"
bash-4.3$ python3 parse_questions.py questions.txt
281952, Flash 11.2 No Longer Supported by Google Play
281993, Netbeans won't open in Ubuntu
답변
세 가지 접근 방식 :
-
어 wk
$ awk -F'": ' '/\"id\"/{id=$NF;} /\"title\"/{ t=$NF; sub(/^""/,"",t); sub(/""$/,"",t); print id,t }' OFS="" file 281952,Flash 11.2 No Longer Supported by Google Play 281993,Netbeans won't open in Ubuntu
-
펄
$ perl -lne '$id=$1 if /id"":\s*(\d+)/; if(/title"":\s*""(.*)""/){print "$id,$1"}' file 281952,Flash 11.2 No Longer Supported by Google Play 281993,Netbeans won't open in Ubuntu
-
펄 호환 정규식과 간단한 펄이있는 GNU grep :
$ grep -oP '(id"":\s*\K.*)|(title"":\s*""\K.*(?=""))' file | perl -pe 'chomp if $.%2' 281952,Flash 11.2 No Longer Supported by Google Play 281993,Netbeans won't open in Ubuntu
답변
이것은 정확히 질문에 대답하거나 문제를 해결하는 것이 아니라 원하지 않는 문자를 제거하려면 tr 을 사용할 수 있습니다 .
cat QueryR | tr -d '}{:"'
그리고 당신은 얻을 것이다 :
답변
이것은 루비로 작성된 또 다른 스크립트입니다. 제목을 쉼표로 유지하므로 열을 손상시키지 않고 스프레드 시트 프로그램으로 쉽게 가져올 수 있습니다.
csvfile = File.open('query-fixed.csv', 'w')
File.open('QueryResults2.csv') do |f|
content = f.read
content.gsub!(/\r\n?/, "\n")
content.each_line do |line|
id, title = '', ''
if line.match('\"id\"')
id = line.split(':')[1].strip[0..-2]
csvfile.write(id + ',')
end
if line.match('\"title\"')
title = line.partition(':')[2].scan(/"(.*)"/)[0][0]
csvfile.write(title + "\n")
end
end
end
프로그램이 실행 된 후 생성 된 출력은 다음과 같습니다.
281952,"Flash 11.2 No Longer Supported by Google Play"
281993,"Netbeans won't open in Ubuntu"