glob을 확장하고 각 파일 이름 앞에 플래그를 삽입합니다.

glob을 확장하고 각 파일 이름 앞에 플래그를 삽입합니다.

다음 구문의 매개변수가 필요한 프로그램이 있습니다.

prog [-f filename | -g filename1 filename2] ...

모든 파일 이름 앞에는 이 플래그가 붙어야 합니다 -f. 예를 들어 다음은 유효한 호출입니다 prog.

prog -f a.txt -g b.txt c.txt -f d.txt
prog -g a.txt b.txt -g c.txt d.txt
prog -f a.txt -f b.txt -f c.txt

...하지만 다음은 그렇지 않습니다.

prog -f a.txt b.txt
prog -f a.txt -g b.txt
prog a.txt

나에 관한 한, 나는 -f선택에 관한 것입니다.

내 디렉토리에는 다음과 같은 파일이 많이 있습니다 .txt.

important-files/
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── filename with spaces.txt

각 파일을 하나씩 나열할 필요가 없도록 하고 싶습니다. 일반적으로 이 작업을 수행하려면 간단한 glob을 사용합니다.

$ prog important-files/*.txt

그러나 이는 다음과 같은 잘못된 호출을 생성하므로 작동하지 않습니다.

$ prog important-files/a.txt important-files/b.txt important-files/c.txt important-files/d.txt 'important-files/filename with spaces.txt'

...정말로 이 전화를 받고 싶을 때:

$ prog -f important-files/a.txt -f important-files/b.txt -f important-files/c.txt -f important-files/d.txt -f 'important-files/filename with spaces.txt'

... 각 파일 이름 -fprog.-g

glob을 사용하고 확장되는 모든 파일에 플래그를 추가하는 가장 짧은 방법은 무엇입니까?

답변1

Null로 구분된 입력을 사용 printf하고 xargs지원합니다.

printf -- '-f\0%s\0' important-files/*.txt | xargs -0 prog

printf인수에 대해 형식 문자열을 반복하므로 전역 확장의 각 파일 이름에 대해 -f파일 이름을 널 문자로 인쇄하고 구분합니다. xargs그런 다음 이를 읽고 매개변수로 변환합니다 prog. 이는 --일부 구현의 printf형식 문자열에 주요 문제가 있기 때문에 필요합니다. -또는 표준인 -으로 대체할 수도 있습니다 .\055

원리와라케쉬의 답변, 대신 와일드카드 확장을 직접 사용하세요.

답변2

zshP이제 글로벌 한정자가 있습니다 ..

이전 버전의 경우 언제든지 다음을 사용할 수 있습니다.

f=(*.txt)
prog -f$^f

$^f만들다rcexpandparam옵션확장의 경우 $f배열이 쉘과 같은 방식으로 확장됩니다 rc.

rc(또는 ) 에서 zsh -o rcexpandparam:

f=(*.txt)
prog -f$f

prog -fa.txt -fb.txtcsh(또는 중괄호 확장을 지원하는 다른 셸)에서 작성하는 것과 약간 비슷 합니다 prog -f{a.txt,b.txt}.

( 두 개의 인수를 전달하는 대신 *.txt(P:-f:)파일 이름이 옵션에 붙어 있다는 점이 다릅니다 . 표준 API를 사용하여 옵션을 구문 분석하는 모든 명령을 포함한 많은 명령은 인수를 옵션에 전달하는 두 가지 방법을 모두 지원합니다.)-ffile.txt-f file.txtgetopt()

fish다음과 같이 배열을 확장할 수도 있습니다.

set f *.txt
prog -f$f

에서는 bash다음을 수행하여 시뮬레이션할 수 있습니다.

f=(*.txt)
prog "${f[@]/#/-f}"

그리고 ksh93:

f=(*.txt)
prog "${f[@]/*/-f\0}"

For -f및 해당 file.txts가 별도의 인수로 전달되는 또 다른 옵션은 zsh배열 압축 연산자를 사용하는 것입니다.

o=-f f=(*.txt); prog ${o:^^f}

원하는 대로 -g이 범위를 확장 할 수 있습니다. 짝수 개의 txt파일이 있다고 가정합니다.

o=(-g '') f=(*.txt); prog ${o:^^f}

-g두 파일에 대한 옵션이 한 번에 전달됩니다. 당신이 얻는 것과 유사합니다:

printf -- '-g\0%s\0%s\0' *.txt | xargs -r0 prog

답변3

Bash를 사용하여 다음을 시도해 보세요.

args=()
for f in important-files/*.txt
do
    args+=(-f "$f")
done
prog "${args[@]}"

이는 공백이 포함된 파일 이름뿐만 아니라 작은 따옴표나 큰 따옴표 또는 개행 문자가 포함된 파일 이름에도 적용됩니다.

대화식으로 사용하기 쉽습니다.

대화형 사용을 용이하게 하려면 함수를 정의하십시오.

progf() { args=(); for f in  "$@"; do args+=(-f "$f"); done; prog "${args[@]}"; }

이 기능은 다음과 같이 사용할 수 있습니다:

progf important-files/*.txt

함수 정의를 영구적으로 만들려면 ~/.bashrc파일에 넣으세요.

답변4

하나. 이를 수행하는 방법은 GNU find/xargs 듀오를 사용하는 것입니다:

cd important-files && \
find . -name '*.txt'  -printf '-f\0%p\0' | xargs -0 -r  prog

관련 정보