sourcecode

xargs로 여러 명령 실행

codebag 2023. 5. 28. 20:45
반응형

xargs로 여러 명령 실행

cat a.txt | xargs -I % echo %

에서, 위의예에서,,xargsecho %명령 인수와 같이.그러나 경우에 따라 인수를 처리하기 위해 하나의 명령 대신 여러 개의 명령이 필요합니다.예:

cat a.txt | xargs -I % {command1; command2; ... }

그렇지만xargs이 양식을 수락하지 않습니다.제가 알고 있는 한 가지 해결책은 명령을 감쌀 수 있는 함수를 정의할 수 있다는 것입니다. 하지만 복잡하기 때문입니다.더 좋은 해결책이 있습니까?

cat a.txt | xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _

...또는 고양이를 쓸모없이 사용하지 않는 경우:

<a.txt xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _

몇 가지 세부 사항을 설명합니다.

  • "$arg"% (의 ).-I에 시대에xargs line됩니다. 데이터 전달 위치sh의 될 수 합니다(예: " 인목수예코대대포데수함체있될내$(rm -rf ~)특히 악의적인 예를 들어)가 코드로 실행되는 것을 방지합니다.

  • 마가지로은, 입니다.-d $'\n' GNU 장니다입을 확장자입니다.xargs입력 파일의 각 행을 별도의 데이터 항목으로 처리합니다. 또는 이거아면니 중 .-0(새 줄 대신 NUL을 예상함)은 xargs가 읽는 스트림에 셸과 같은(그러나 셸 호환되지는 않음) 구문 분석을 적용하려는 것을 방지하기 위해 필요합니다. (GNU xargs가 없다면, 사용할 수 있습니다.)tr '\n' '\0' <a.txt | xargs -0 ...없이 줄 위주의 독서를 하는 것-d).

  • _는 의자표입다니시자의 표시자입니다.$0다른위데값이하추해기록도에 의해 되는 것.xargs 되다$1그리고 그 이후, 이것은 a의 기본 값 집합이 됩니다.for루프가 반복됩니다.

사용할 수 있습니다.

cat file.txt | xargs -i  sh -c 'command {} | command2 {} && command3 {}'

= 텍스트 파일의 각 줄에 대한 변수

GNU Parallel을 사용하면 다음을 수행할 수 있습니다.

cat a.txt | parallel 'command1 {}; command2 {}; ...; '

보안상의 이유로 패키지 관리자를 사용하여 설치하는 것이 좋습니다.하지만 그렇게 할 수 없다면 이 10초짜리 설치를 사용할 수 있습니다.

10초 동안 설치하면 전체 설치를 시도하고, 실패하면 개인 설치를 시도하며, 실패하면 최소 설치를 시도합니다.

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

모드가 ).| sh) :

cat a.txt | xargs -I % echo "command1; command2; ... " | sh

파이프에서도 작동합니다.

cat a.txt | xargs -I % echo "echo % | cat " | sh

이것은 잔주름이나 고양이가 없는 또 다른 접근법일 뿐입니다.

while read stuff; do
  command1 "$stuff"
  command2 "$stuff"
  ...
done < a.txt

이것이 가장 안전한 버전인 것 같습니다.

tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''

(-0할 수 제할수 며있으거,,tr리디렉션으로 대체하거나 파일을 null로 구분된 파일로 대체할 수 있습니다.제가 주로 사용하기 때문에 주로 그 안에 있습니다.xargs와 함께find와 함께-print0output) (은 력출이에도 수 .) (은또있을수있습다니이관련한것▁output다있이니▁(습.xargs 없는 -0확장)

Args는 실행 시 매개 변수를 배열로 셸에 전달하므로 안전합니다. 껍적질 (도어at))bash그러면 모든 프로세스가 다음을 사용하여 얻을 때 변경되지 않은 배열로 다른 프로세스에 전달됩니다.["$@"][1]

사용하는 경우...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''문자열에 큰따옴표가 있으면 할당이 실패합니다.이는 다음을 사용하는 모든 변형 모델에 해당됩니다.-i또는-I에 입력 따옴표, 기호할 수 있습니다

명령에서 한 번에 하나의 파라미터만 사용할 수 있는 경우:

tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''

또는 프로세스가 다소 적은 경우:

tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''

GNU GNU가 에는 다음과 같이 하십시오.xargs아니면 다른 것과 함께.-P할 수 각 는 각의 매개 할 수 .

tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''

이것은 입력의 특수 문자에 대해 견고해야 합니다. (입력이 null로 구분된 경우)tr일부 줄에 새 줄이 포함되어 있으면 버전에서 잘못된 입력을 받지만 새 줄로 구분된 파일에서는 이를 피할 수 없습니다.

대 한 첫 번 매 개 변 수 째 음에 대한 빈 첫 bash -c그 이유는 다음과 같습니다. ( 페이지에서) (고마워요 @clacke)

-c   If the -c option is present, then  commands  are  read  from  the  first  non-option  argument  com‐
     mand_string.   If there are arguments after the command_string, the first argument is assigned to $0
     and any remaining arguments are assigned to the positional parameters.  The assignment  to  $0  sets
     the name of the shell, which is used in warning and error messages.

제가 하는 한 가지 일은 이 함수를 .bashrc/.profile에 추가하는 것입니다.

function each() {
    while read line; do
        for f in "$@"; do
            $f $line
        done
    done
}

그러면 당신은 다음과 같은 것들을 할 수 있습니다.

... | each command1 command2 "command3 has spaces"

xargs 또는 -exec보다 장황하지 않습니다.명령의 임의 위치에 있는 읽기 값을 각 위치에 삽입하도록 함수를 수정할 수도 있습니다.

저에게 효과가 있는 또 다른 가능한 해결책은 다음과 같습니다.

cat a.txt | xargs bash -c 'command1 $@; command2 $@' bash

끝에 있는 'bash'를 기록합니다. bash는 argv[0]로 전달된다고 가정합니다.이 구문을 사용하지 않으면 각 명령에 대한 첫 번째 매개 변수가 손실됩니다.어떤 단어든 상관없습니다.

예:

cat a.txt | xargs -n 5 bash -c 'echo -n `date +%Y%m%d-%H%M%S:` ; echo " data: " $@; echo "data again: " $@' bash

이것에 대한 나의 현재 BKM은.

... | xargs -n1 -I % perl -e 'system("echo 1 %"); system("echo 2 %");'

유감스럽게도 이것은 bash보다 설치될 가능성이 적은 perl을 사용하지만 허용된 답변보다 더 많은 입력을 처리합니다. (저는 perl에 의존하지 않는 유비쿼터스 버전을 환영합니다.)

@에 대한 키스 톰슨의 제안

 ... | xargs -I % sh -c 'command1; command2; ...'

입력에 셸 주석 문자 #이 없으면 좋습니다. 이 경우 첫 번째 명령의 일부와 두 번째 명령의 모든 부분이 잘립니다.

입력이 ls 또는 find와 같은 파일 시스템 목록에서 파생되고 편집자가 이름에 #이 있는 임시 파일을 만드는 경우 해시 #는 매우 일반적일 수 있습니다.

문제의 예:

$ bash 1366 $>  /bin/ls | cat
#Makefile#
#README#
Makefile
README

이런, 여기 문제가 있습니다.

$ bash 1367 $>  ls | xargs -n1 -I % sh -i -c 'echo 1 %; echo 2 %'
1
1
1
1 Makefile
2 Makefile
1 README
2 README

아, 그게 더 낫군요.

$ bash 1368 $>  ls | xargs -n1 -I % perl -e 'system("echo 1 %"); system("echo 2 %");'
1 #Makefile#
2 #Makefile#
1 #README#
2 #README#
1 Makefile
2 Makefile
1 README
2 README
$ bash 1369 $>  

사용해 보십시오.

git config --global alias.all '!f() { find . -d -name ".git" | sed s/\\/\.git//g | xargs -P10 -I{} git --git-dir={}/.git --work-tree={} $1; }; f'

10개의 스레드를 병렬로 실행하고 폴더 구조의 모든 저장소에 원하는 모든 git 명령을 수행합니다.레포가 깊이가 1레벨이든 n레벨이든 상관없습니다.

예:git all pull

저는 그 문제를 해결할 좋은 생각이 있습니다. ㅠㅠㅠㅠㅠㅠㅠmcmd그러면 할 수 있습니다.

find . -type f | xargs -i mcmd echo {} @@ cat {} @pipe sed -n '1,3p'

mcmd내용은 다음과 같습니다.

echo $* | sed -e 's/@@/\n/g' -e 's/@pipe/|/g' | csh

언급URL : https://stackoverflow.com/questions/6958689/running-multiple-commands-with-xargs

반응형