다음과 같은 CSV가 있다고 가정해 보겠습니다.
$ cat test.csv
id,domain
1,foo.com
2,bar.com
를 사용하면 mlr put
Miller에서 정의할 수 있는 한 모든 기능을 CSV의 필드에 쉽게 매핑할 수 있습니다.DSL. 예를 들어 mlr --csv put '$id = $id + 1'
각 레코드마다 1씩 증가합니다.id
하지만 Miller DSL에서 함수를 정의할 수 없다면(아마도 순수 함수가 아니기 때문에) 어떻게 될까요? CSV의 각 도메인을 IP 주소에 매핑한다고 가정해 보겠습니다. 나는 비슷한 것을 하고 싶다 mlr --csv put '$ip = shell("nslookup $domain")
. 찾을 수 있는 단축키가 있나요?
현재 입력 필드를 별도의 파일로 추출하고 이를 별도의 쉘 스크립트로 다시 작성한 다음 결과를 다시 추가하고 있습니다 mlr join
. 그러나 내 CSV는 따옴표, 쉼표 및 줄바꿈으로 가득 차 있기 때문에 이는 매우 혼란스럽습니다. Miller에게 의존하기보다는 스스로 신중하게 처리해야 합니다.
답변1
고쳐 쓰다: 2019년 9월 현재, 이것
system()
DSL 기능이 목적으로 사용될 수 있습니다.
Miller DSL에서 외부 명령 호출
외부 명령 호출에 대한 Miller DSL 참조 섹션리디렉션 출력 문:
이것인쇄,덤프,티,배출량,방사, 그리고방사두 키워드를 모두 사용하면 출력을 하나 이상의 파일로 리디렉션할 수 있습니다.또는 파이프 명령.
문서에서 이를 찾을 수 없지만(예제에서 추론하는 것 제외) 파이프라인-to 명령과 함께 이러한 문을 사용하는 구문은 다음과 같습니다 {statement} | {quoted-shell-command}, {unquoted-mlr-expression}
.
$ mlr --csv put 'tee | "tr [a-z] [A-Z]", $*' test.csv
id,domain
1,foo.com
2,bar.com
ID,DOMAIN
1,FOO.COM
2,BAR.COM
파이프 출력은 Miller의 출력(이 경우 tee
스트림이 영향을 받지 않고 put
방출되지 않으므로 변경되지 않은 입력) 뒤에 나타납니다. 억제된 출력을 사용 put
하고 개별 필드를 추출하는 대신 -q
IP 주소 목록을 얻을 수 있습니다.print $domain
tee $*
$ mlr --csv put -q 'print | "xargs dig +short", $domain' test.csv
23.23.86.44
104.27.138.186
104.27.139.186
Miller는 여기서 우리를 위해 많은 일을 하지 않습니다. xargs
표준 입력을 인수로 변환 해야 합니다 ( dig
표준 입력의 필드는 허용되지 않으므로). 또한 dig
의 출력에는 개행 문자가 포함되어 있습니다. 이는 출력이 더 이상 입력과 일대일로 일치하지 않음을 의미합니다. Unix 철학에 따르면, 그것이 내가 필요한 전부라면 mlr
그냥 끝까지 파이프하는 것이 더 쉬울 것입니다 .mlr --headerless-csv-output cut -f domain
외부 명령의 출력을 입력에 연결
내가 정말로 원하는 것은 Miller DSL의 내부 스트림 변수에 외부 명령을 호출한 결과를 할당하는 것입니다., 내가 아는 한, 이것은 불가능합니다. 그러나 xargs
교환을 통해암소 비슷한 일종의 영양parallel
, 이 --tag
옵션을 사용하여 제공하는 인수를 추적 dig
하고 유연한 동시 I/O의 이점을 누릴 수 있습니다.
$ mlr --csv --headerless-csv-output cut -f domain test.csv | parallel --tag dig +short
foo.com 23.23.86.44
bar.com 104.27.139.186
bar.com 104.27.138.186
CSV를 다루고 있으므로 이름( ) 이 아닌 parallel
위치( )로 필드에 액세스해야 하지만 실제로는 직접 처리할 수 있습니다.{2}
domain
$ < test.csv parallel -C "," --skip-first-line --tagstring {2} dig +short {2}
foo.com 23.23.86.44
bar.com 104.27.139.186
bar.com 104.27.138.186
이는 탭으로 구분된 쌍 목록이므로 (domain, ip)
.txt를 사용하여 헤더가 있는 CSV로 다시 변환할 수 있습니다 mlr --t2c --implicit-csv-header label domain,ip
. 그런 다음 출력과 원본 데이터 test.csv
모두에 필드가 있으므로 이를 사용하여 여러 값이 내포된 단일 출력 테이블을 생성 domain
할 수 있습니다 .mlr join
mlr nest
bar.com
$ mlr --csv cut -f domain test.csv | \
parallel --skip-first-line --tag dig +short | \
mlr --t2c --implicit-csv-header label domain,ip | \
mlr --c2p --barred join -f test.csv -j domain then \
nest --implode --values --across-records -f ip
+---------+----+-------------------------------+
| domain | id | ip |
+---------+----+-------------------------------+
| foo.com | 1 | 23.23.86.44 |
| bar.com | 2 | 104.27.138.186;104.27.139.186 |
+---------+----+-------------------------------+