python3에서 다음 jq
명령 을 실행하고 싶습니다 subprocess.Popen()
.
$ jq 'INDEX(.images[]; .id) as $imgs | {
"filename_with_label":[
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label}
]
}' image_data_annotation.json > image_data_annotation_with_label.json
첫 번째 명령 줄 인수에는 작은 따옴표 안에 점, 달러 기호, 큰 따옴표가 포함되어 있습니다. 참고로, jq
json 파일 처리를위한 JSON 프로세서 유틸리티입니다.
jq
유틸리티로 JSON 파일 처리를 자동화하기 위해 다음 python3 스크립트를 작성했습니다 .
#!python3
# file name: letter_image_tool.py
import os, subprocess
"""
command line example to automate
$ jq 'INDEX(.images[]; .id) as $imgs | {
"filename_with_label":[
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label}
]
}' image_data_annotation.json > image_data_annotation_with_label.json
"""
# define first command line argument
jq_filter='\'INDEX(.images[]; .id) as $imgs | { "filename_with_label" : [ .annotations[] | select(.attributes.type=="letter" ) | $imgs[.image_id] + {label:.text} | {id:.id} + {filename:.file_name} + {label:.label} ] }\''
input_json_files= [ "image_data_annotation.json"]
output_json_files= []
for input_json in input_json_files:
print("Processing %s" %(input_json))
filename, ext = os.path.splitext(input_json)
output_json = filename + "_with_label" + ext
output_json_files.append(output_json)
print("output file is : %s" %(output_json))
#jq_command ='jq' + " " + jq_filter, input_json + ' > ' + output_json
jq_command =['jq', jq_filter, input_json + ' > ' + output_json]
print(jq_command)
subprocess.Popen(jq_command, shell=True)
bash에서 위의 python 스크립트를 실행하면 다음과 같은 결과가 발생합니다.
$ ./letter_image_tool.py
Processing image_data_annotation.json
output file is : image_data_annotation_with_label.json
['jq', '\'INDEX(.images[]; .id) as $imgs | { "filename_with_label" : [ .annotations[] | select(.attributes.type=="letter" ) | $imgs[.image_id] + {label:.text} | {id:.id} + {filename:.file_name} + {label:.label} ] }\'', 'image_data_annotation.json > image_data_annotation_with_label.json']
jq - commandline JSON processor [version 1.6-124-gccc79e5-dirty]
Usage: jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.
The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).
For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq
Example:
$ echo '{"foo": 0}' | jq .
{
"foo": 0
}
For a listing of options, use jq --help.
jq
유틸리티 의 첫 번째 인수는 처리하지 않습니다 .
'INDEX(.images[]; .id) as $imgs | {
"filename_with_label":[
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label}
]
}'
첫 번째 인수는 위의 스 니펫과 같이 작은 따옴표로 묶어야하지만 스크립트가 처리하지 않습니다.
주요 문제는 첫 번째 명령 줄 인수 ( jq_filter
위의 Python 스크립트에서)에 사용 된 점, 달러 기호, 작은 따옴표 및 큰 따옴표와 관련이 있다고 생각합니다 . 그러나 나는 bash와 관련된 이런 종류의 복잡한 메타 문자를 다루는 방법을 모릅니다.
위의 문제를 해결하려면 어떻게해야합니까?
읽어 주셔서 감사합니다.
내 솔루션으로 업데이트
jq_filter 정의에 대한 삼중 따옴표 및 다음과 같이 공백으로 분리 된 결합
#!python3
# file name: letter_image_tool.py
import os, subprocess
"""
command line example to automate
$ jq 'INDEX(.images[]; .id) as $imgs | {
"filename_with_label":[
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label}
]
}' image_data_annotation.json > image_data_annotation_with_label.json
"""
# define first command line argument with triple quotes
jq_filter=""" 'INDEX(.images[]; .id) as $imgs | {
"filename_with_label" : [
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label} ] } ' """
input_json_files= [ "image_data_annotation.json"]
output_json_files= []
for input_json in input_json_files:
print("Processing %s" %(input_json))
filename, ext = os.path.splitext(input_json)
output_json = filename + "_with_label" + ext
output_json_files.append(output_json)
print("output file is : %s" %(output_json))
#jq_command ='jq' + " " + jq_filter, input_json + ' > ' + output_json
# jq command composed with space separated join
jq_command =' '.join['jq', jq_filter, input_json, ' > ', output_json]
print(jq_command)
# shell keyword argument should be set True
subprocess.Popen(jq_command, shell=True)
삼중 큰 따옴표를 사용하면 jq_filter는 한 줄로 정의하는 대신 여러 줄로 된 정의를 사용하여 더 쉽게 읽을 수 있습니다.
작은 따옴표가 필요한 이유는 쉘이 인수 확장을 수행하지 못하도록하기 위함입니다. 이는 shell=True
. 이것이 설정되지 않으면 쉘은 인수를 건드리지 않으며 인수를 "보호"할 필요가 없습니다.
그러나 셸은 stdout
리디렉션 (예 :) 도 담당합니다 [... '>', output_json]
. 셸을 사용하지 않고 대신 Python 코드에서 리디렉션을 처리해야합니다. 그러나 이는 인수 stdout=...
를에 추가하는 것만 큼 간단 합니다 Popen
.
All-in-all 이것은 코드를 다음과 같이 다시 작성할 수 있음을 의미합니다.
import os
import subprocess
# Still define first command line argument with triple quotes for readability
# Note that there are no single quotes though
jq_filter = """INDEX(.images[]; .id) as $imgs | {
"filename_with_label" : [
.annotations[]
| select(.attributes.type=="letter" )
| $imgs[.image_id] + {label:.text}
| {id:.id} + {filename:.file_name} + {label:.label} ] }"""
input_json_files = ["image_data_annotation.json"]
output_json_files = []
for input_json in input_json_files:
print("Processing %s" % (input_json))
filename, ext = os.path.splitext(input_json)
output_json = filename + "_with_label" + ext
output_json_files.append(output_json)
print("output file is : %s" % (output_json))
# Keep command as list, since this is what we need when NOT using shell=True
# Note also that the redirect and the output file are not parts of the argument list
jq_command = ['jq', jq_filter, input_json]
# shell keyword argument should NOT be set True
# Instead redirect stdout to an out_file
# (We must open the file for writing before redirecting)
with open(output_json, "w") as out_file:
subprocess.Popen(jq_command, stdout=out_file)
일반적으로 shell=True
인젝션 공격은 셸에 대한 전체 액세스 권한을 부여 할 수 있으므로 코드에 대한 또 다른 공격 벡터가 열리므로 사용하지 않는 것이 좋습니다 . 또한 셸을 사용하지 않는 또 다른 작은 이점은 추가 셸 프로세스가 필요하지 않기 때문에 생성 된 하위 프로세스의 수가 줄어든다는 것입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다