xargs-각 인수를 매개 변수로 추가


12

나는 주어진 알고 l="a b c",

echo $l | xargs ls

수확량

ls a b c

어느 구성 수확량

mycommand -f a -f b -f c

답변:


13

그것을하는 한 가지 방법 :

echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand

이것은 가정 a, bc공백, 줄 바꿈, 따옴표 또는 백 슬래시를 포함하지 않습니다. :)

GNU findutil를 사용하면 일반적인 경우를 처리 할 수 ​​있지만 약간 더 복잡합니다.

echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand

당신은 대체 할 수있는 |그에서 표시되지 않습니다, 다른 문자로 구분 a, b또는 c.

편집 : @MichaelMol이 지적한 것처럼 인수 목록이 너무 길면 전달할 수있는 최대 인수 길이가 넘칠 위험이 있습니다 mycommand. 이 경우 마지막 xargs은 목록을 분할하고의 다른 사본을 실행 mycommand하며 종료되지 않은 채로 남겨질 위험이 있습니다 -f. 그 상황에 대해 걱정한다면 마지막 xargs -0으로 다음과 같이 바꿀 수 있습니다 .

... | xargs -x -0 mycommand

이렇게해도 문제가 해결되지는 않지만 mycommand인수 목록이 너무 길면 실행이 중단 됩니다.


1
짝을 이루는 매개 변수 를 초과 ARG_MAX하여 -f분리 될 위험이 있습니다.
Michael Mol

@MichaelMol 좋은 지적이지만,에 대해 더 많이 알지 못하고 그 상황을 처리하는 의미있는 방법은 없다고 생각 mycommand합니다. 당신은 항상 -x마지막에 추가 할 수 있습니다 xargs.
Satō Katsura

나는 적절한 솔루션을 사용하는 아마 생각 xargs전혀, 그냥 사용 find이 사용할 수 있는지. 이 솔루션은 위험합니다. 적어도 당신의 대답에 실패 사례에 대해 경고해야합니다.
Michael Mol

@MichaelMol find특히 초기 인수가 파일 이름이 아닌 경우 더 나은 일반적인 솔루션이 어떻게 될지 알지 못합니다. :)
Satō Katsura

우리는 초기 논증이 무엇인지 모른다. 우리는 질문에 영감을 준 시나리오가 아니라 주어진 예만 볼 수 있습니다. 직감에 따르면 인수 이름 -f이이고 설명에 사용 된 예제 도구를 ls사용하면 @ not-a-user가 파일 이름을 처리하고 있습니다. 그리고 명령 줄 을 구성 할 수 find있는 -exec인수를 제공하면 좋습니다 . ( 두 번 이상 실행할 수있는 한, 그렇지 않은 경우 여기에 다른 문제가 있습니다 ...)mycommandxargs
Michael Mol

5

이를 해결하는 더 좋은 방법은 다음과 같습니다.

  • 에서 zsh:

    l=(a b c)
    mycommand -f$^l

    또는 배열 압축을 사용하여 인수가 옵션에 첨부되지 않습니다.

    l=(a b c) o=(-f)
    mycommand "${o:^^l}"

    이렇게하면 l배열에 공백 또는 공백이있는 다른 요소가 포함 된 빈 요소 또는 요소가 포함되어 있으면 여전히 작동합니다 xargs. 예:

    $ l=(a '' '"' 'x y' c) o=(-f)
    $ printf '<%s>\n' "${o:^^l}"
    <-f>
    <a>
    <-f>
    <>
    <-f>
    <">
    <-f>
    <x y>
    <-f>
    <c>
  • 에서 rc:

    l=(a b c)
    mycommand -f$l
  • 에서 fish:

    set l a b c
    mycommand -f$l

(AFAIK는 rcfish더 배열을 압축 없다)

와 같은 구식 Bourne과 같은 쉘을 사용 bash하면 항상 할 수 있습니다 (여전히 $@배열 요소에 문자를 허용 ).

set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"

1
bash에서 다른 방법은 명명 된 배열 변수를 사용하는 것입니다. for i; do args+=('-f' "$i");done; mycommand "${args[@]}". 이것이 더 빠르지 만 IDK가 배열에 2 개의 요소를 추가하면 O (n)이어야하는 것처럼 보이지만 set루프는 매번 누적 된 인수 목록을 복사하고 다시 구문 분석 할 것입니다 (O (n ^ 2)).
Peter Cordes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.