xargs를 사용하여 여러 명령 호출
cat a.txt | xargs -I % echo %
위의 예에서 xargs는 echo %
명령 인수로 사용됩니다. 그러나 어떤 경우에는 인수 대신 하나의 인수를 처리하기 위해 여러 명령이 필요합니다. 예를 들면 다음과 같습니다.
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
명령 줄) 보안상의 이유로입니다 : 데이터 전달sh
의 명령 줄 인수 목록 대신 데이터 같은 (포함 할 수 있다는 코드 방지의 콘텐츠로 대체$(rm -rf ~)
, 특히 걸릴 악성 예) 코드로 실행되지 않습니다.마찬가지로, 사용
-d $'\n'
하는 GNU 확장xargs
은 입력 파일의 각 줄을 별도의 데이터 항목으로 취급합니다.-0
xargs가 읽은 스트림에 쉘과 유사한 (그러나 쉘과 호환 되지는 않지만 ) 구문 분석을 적용하지 못하게하려면 이 또는 개행 문자 대신 NUL이 필요합니다 . (GNU xargs가없는 경우을 사용tr '\n' '\0' <a.txt | xargs -0 ...
하지 않고 줄 지향 읽기를 얻을 수 있습니다-d
).는
_
플레이스 홀더이기$0
등이 추가로 다른 데이터 값xargs
이 될$1
가치관의 기본 설정되는 일이있는 전방 및for
루프 반복 처리.
GNU Parallel을 사용하면 다음을 수행 할 수 있습니다.
cat a.txt | parallel 'command1 {}; command2 {}; ...; '
자세한 내용은 소개 동영상을 참조하십시오. https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
이것은 xargs 또는 cat이없는 또 다른 접근법입니다.
while read stuff; do
command1 "$stuff"
command2 "$stuff"
...
done < a.txt
당신이 사용할 수있는
cat file.txt | xargs -i sh -c 'command {} | command2 {} && command3 {}'
{} = 텍스트 파일의 각 줄에 대한 변수
내가하는 한 가지는 .bashrc / .profile 에이 기능을 추가하는 것입니다.
function each() {
while read line; do
for f in "$@"; do
$f $line
done
done
}
다음과 같은 일을 할 수 있습니다
... | each command1 command2 "command3 has spaces"
xargs 또는 -exec보다 덜 장황합니다. 또한 해당 동작이 필요한 경우 명령의 임의 위치에서 읽은 값을 각 위치에 삽입하도록 함수를 수정할 수도 있습니다.
나는 드라이 런 모드를 허용하는 스타일을 선호한다 | sh
.
cat a.txt | xargs -I % echo "command1; command2; ... " | sh
파이프와도 작동합니다.
cat a.txt | xargs -I % echo "echo % | cat " | sh
파티에 조금 늦었 어
마이그레이션하기 전에 수천 개의 작은 파일로 디렉토리를 압축하는 데 아래 형식을 사용합니다. 명령 안에 작은 따옴표가 필요하지 않으면 작동합니다.
약간의 수정으로 누군가에게 유용 할 것이라고 확신합니다. Cygwin
(바분) 에서 테스트
find . -maxdepth 1 ! -path . -type d -print0 | xargs -0 -I @@ bash -c '{ tar caf "@@.tar.lzop" "@@" && echo Completed compressing directory "@@" ; }'
find .
여기 찾기
-maxdepth 1
하위 디렉토리로 이동하지 마십시오
! -path .
제외합니다. / 현재 디렉토리 경로
-type d
만 디렉토리와 일치합니다.
-print0
null 바이트로 분리 된 출력 \ 0
| xargs
xargs로 파이프
-0
입력이 널로 분리 된 바이트입니다.
-I @@
자리 표시자는 @@입니다. @@을 입력으로 바꿉니다.
bash -c '...'
Bash 명령 실행
{...}
명령 그룹화
&&
이전 명령이 성공적으로 종료 된 경우에만 다음 명령을 실행 하십시오 (종료 0).
최종 ;
은 중요합니다. 그렇지 않으면 실패합니다.
산출:
Completed compressing directory ./Directory1 with meta characters in it
Completed compressing directory ./Directory2 with meta characters in it
Completed compressing directory ./Directory3 with meta characters in it
2018 년 7 월 업데이트 :
해킹과 장난을 좋아한다면 흥미로운 것이 있습니다.
echo "a b c" > a.txt
echo "123" >> a.txt
echo "###this is a comment" >> a.txt
cat a.txt
myCommandWithDifferentQuotes=$(cat <<'EOF'
echo "command 1: $@"; echo 'will you do the fandango?'; echo "command 2: $@"; echo
EOF
)
< a.txt xargs -I @@ bash -c "$myCommandWithDifferentQuotes" -- @@
산출:
command 1: a b c
will you do the fandango?
command 2: a b c
command 1: 123
will you do the fandango?
command 2: 123
command 1: ###this is a comment
will you do the fandango?
command 2: ###this is a comment
설명 :
- 하나의 라이너 스크립트를 작성하고 변수에 저장
- xargs
읽어 a.txt
하고 실행하는 그것을 bash
스크립트
- @@
확인 전체 라인이 통과 될 때마다한다
- 퍼팅 @@
후 --
확인합니다 @@
에 위치 매개 변수 입력으로 촬영 bash
명령이 아닌 bash
시작 OPTION
, 즉, 추천 -c
자체하는 수단run command
--
마법, 그것은 즉, 다른 많은 것들, 작동 ssh
도,kubectl
나를 위해 작동하는 또 다른 가능한 해결책은 다음과 같습니다.
cat a.txt | xargs bash -c 'command1 $@; command2 $@' bash
끝에 'bash'를 주목하십시오-나는 그것이 argv [0]으로 bash에 전달된다고 가정합니다. 이 구문이 없으면 각 명령의 첫 번째 매개 변수가 손실됩니다. 어떤 단어라도 될 수 있습니다.
예:
cat a.txt | xargs -n 5 bash -c 'echo -n `date +%Y%m%d-%H%M%S:` ; echo " data: " $@; echo "data again: " $@' bash
가장 안전한 버전 인 것 같습니다.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
제거하고 tr
리디렉션으로 대체 할 수 있습니다 (또는 파일을 null로 구분 된 파일로 대체 할 수 있습니다). 주로 출력 xargs
과 find
함께 사용하기 때문에 주로 존재 -print0
합니다) ( 확장자가 xargs
없는 버전 에서도 관련이있을 수 있습니다 -0
)
args는 매개 변수를 실행할 때 매개 변수를 셸에 배열로 전달하므로 안전합니다. 쉘은 (적어도 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 xargs
또는 다른 -P
확장 프로그램이 있고 32 개의 프로세스를 병렬로 실행하려는 경우 각 명령에 대해 매개 변수가 10 개 이하인 프로세스를 각각 실행하십시오.
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
이것은 입력의 특수 문자에 대해 강력해야합니다. (입력이 널 (null)로 분리 된 tr
경우) 일부 행에 개행이 포함되어 있으면 버전에서 유효하지 않은 입력을 받지만 개행으로 구분 된 파일에서는 피할 수 없습니다.
빈 첫 번째 매개 변수 bash -c
는 다음과 같습니다. ( bash
Man 페이지에서 ) (감사합니다 @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.
이것에 대한 나의 현재 BKM은
... | xargs -n1 -I % perl -e 'system("echo 1 %"); system("echo 2 %");'
불행히도 이것은 bash를 사용하는 펄을 사용하는 것이 불행하다. 그러나 허용 된 답변보다 더 많은 입력을 처리합니다. (펄에 의존하지 않는 유비쿼터스 버전을 환영합니다.)
@KeithThompson의 제안
... | 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 $>
참고 URL : https://stackoverflow.com/questions/6958689/calling-multiple-commands-with-xargs
'IT' 카테고리의 다른 글
첫 번째 오류 발생시 중지 (0) | 2020.03.22 |
---|---|
Visual Basic 및 BASIC에서 DIM은 무엇을 의미합니까? (0) | 2020.03.22 |
values.xml에서 AppCompat v7 r21이 오류를 반환합니까? (0) | 2020.03.22 |
이 빌드 중에 "코드 9009로 종료"란 무엇을 의미합니까? (0) | 2020.03.22 |
원격 서버에서 로컬 시스템으로 rsync를 사용하여 파일 복사 (0) | 2020.03.22 |