답변:
차이점은 대상 프로그램이 수용하는 데이터에 있습니다.
파이프 만 사용하는 경우 STDIN (표준 입력 스트림)의 데이터를 한 번에 한 줄씩 정렬 할 수있는 원시 데이터 더미로 수신합니다. 그러나 일부 프로그램은 표준으로 명령을 수락하지 않으며 명령에 대한 인수에서 철자를 기대합니다. 예를 들어 touch
, 명령 행에서 다음과 같이 파일 이름을 매개 변수로 사용합니다 touch file1.txt
.
당신은 파일 이름을 출력하는 프로그램이 있으면 밖으로 표준을 하고 사용하려는 인자로 에 touch
, 당신은 사용해야하는 xargs
표준 입력 스트림 데이터를 읽고 명령을 공백으로 구분 인수로 각 라인을 변환한다.
이 두 가지는 동일합니다.
# touch file1.txt
# echo file1.txt | xargs touch
xargs
정확히 무엇을하고 있고 왜 필요한지 알지 않는 한 사용 하지 마십시오 . xargs
변환을 강제하는 데 사용 하는 것보다 작업을 수행하는 더 좋은 방법이있는 경우가 종종 있습니다. 변환 과정에는 탈출과 단어 확장 등과 같은 잠재적 인 함정이 있습니다.
xargs -0
) find -print0
.
xargs
공백으로 구분 된 args로 쉘을 통해 프로그램을 호출 합니까 , 아니면 실제로 내부적으로 인수 목록을 구성 합니까 (예 : execv
/ 와 함께 사용 execp
)?
-d \n
BSD xargs (OSX et al)는이 옵션을 지원하지 않는 것처럼 보이지만 GNU xargs (Linux 및 기타 몇 가지에서 사용됨)를 사용하면 구분 기호로 줄 바꿈을 지정할 수 있습니다 .
이미 제공된 답변을 확장하려면 xargs
오늘날의 멀티 코어 및 분산 컴퓨팅 환경에서 점점 중요 해지고있는 멋진 일을 처리 할 수 있습니다. 프로세스 작업을 병렬 처리 할 수 있습니다.
예를 들면 다음과 같습니다.
$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8
한 번에 세 개의 프로세스를 사용하여 * .wav => * .flac를 인코딩합니다 ( -P 3
).
-exec
매개 변수는 작업을 병렬 처리하지 않습니다.
-0
인수가xargs
NULL
문자를 입력 항목 분리 문자로 간주하도록 하는 인수 에 유의하십시오 . find -print0
NULL로 구분 된 항목을 출력합니다. 공백, 따옴표 또는 기타 특수 문자를 포함 할 수있는 파일 이름에 유용합니다.
xargs는 stdin에 파일 경로 목록이 있고 그와 함께 무언가를 수행하려고 할 때 특히 유용합니다. 예를 들면 다음과 같습니다.
$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
이 단계를 단계별로 살펴 보자.
$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....
다시 말해, 우리의 입력은 우리가하고 싶은 경로의 목록입니다.
이러한 경로에서 xargs가 수행하는 작업을 찾으 echo
려면 명령 앞에 다음과 같이 추가하는 것이 좋습니다 .
$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....
-n 1
인수는 xargs를 자체의 명령으로 각 라인을 설정하게됩니다. sed -i "s/color/colour/g"
명령의 모든 항목을 대체 할 color
과를 colour
지정한 파일.
경로에 공백이없는 경우에만 작동합니다. 그렇게하면 -0
플래그 를 전달하여 널 종료 경로를 xargs에 대한 입력으로 사용해야합니다 . 사용 예는 다음과 같습니다.
$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"
위에서 설명한 것과 동일하지만 경로 중 하나에 공백이 있으면 작동합니다.
이것은 find
또는 같은 출력으로 파일 이름을 생성하는 모든 명령에서 작동합니다 locate
. 파일이 많은 git 저장소에서 사용하면 다음과 같이 git grep -l
대신 사용하는 것이 더 효율적일 수 있습니다 git ls-files
.
$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
이 git grep -l "color" "*.tex"
명령은 "color"라는 문구가 포함 된 "* .tex"파일 목록을 제공합니다.
첫 번째 주장은 그 차이를 아주 잘 보여줍니다.
\ls | grep Cases | less
ls
및에서 생성 한 파일 이름 목록을 찾아 볼 수 있습니다 grep
. 파일 이름이 중요하지는 않지만 텍스트 일뿐입니다.
\ls | grep Cases | xargs less
명령의 첫 부분에서 이름이 생성 된 파일을 찾아 볼 수 있습니다. xargs
입력 및 명령 줄에서 명령으로 파일 이름의 목록을 받아,의 파일 이름으로 명령을 실행 의 명령 행.
사용을 고려하는 경우 xargs
에, 공백으로 구분 : 그것은 이상한 방식으로 서식 입력 기대하는 마음에 계속 \
, '
그리고 "
(때문에 비정상적인 방법으로 인용 부호를 사용 \
하지 특수 내부 인용 부호)입니다. xargs
파일 이름에 공백이나가 포함되지 않은 경우 에만 사용 하십시오 \'"
.
xargs
있는 -0, --null
옵션이 있습니다 (나는 당신에게서 그것을 배웠을 가능성이 높습니다 :), 나는 당신이 옵션 없음 xarg
전화를 말하는 것으로 가정하지만 인용에 대한 언급에 의지 합니다. 관련 링크 또는 예가 있습니까? . ... (PS | xargs less
편리한 "속임수"1 .. 감사합니다 ..입니다
귀하의 예에서는 원하는 것을 정확하고 안전하게 수행 할 xargs
것이므로 전혀 사용할 필요가 없습니다 find
.
정확히 사용하려는 find
것은 다음과 같습니다.
find -maxdepth 1 -name '*Cases*' -exec touch {} +
이 예에서는 -maxdepth 1
현재 디렉토리에서만 검색하고 하위 디렉토리로 내려 가지 않음을 의미합니다. 기본적으로 find는 maxdepth로 제한하지 않는 한 모든 하위 디렉토리 (주로 원하는 것)를 찾습니다. 는 {}
그 자리에 대체하고,이 얻을 것이다 파일의 이름 +
이 끝 명령 마커 중 하나, 다른 존재입니다 ;
. 차이점은 ;
각 파일에서 명령을 한 번에 하나씩 실행 한다는 의미이고 +
모든 파일에서 명령을 한 번에 실행한다는 의미입니다. 그러나 셸이 아마도 ;
자체 해석을 시도 할 것이므로 \;
또는 으로 이스케이프해야합니다 ';'
. 예, find
이와 같은 작은 성가심이 있지만 그 힘은 그것을 보완하는 것 이상입니다.
모두 find
와는 xargs
처음에 배울 까다로운 있습니다. 배우기 xargs
위해 -p
또는 --interactive
옵션을 사용하여 실행하려고 하는 명령을 표시하고 실행할 것인지 묻는 메시지를 표시하십시오.
마찬가지로 대신 명령을 실행할지 묻는 메시지 대신 find
사용할 수 있습니다 .-ok
-exec
그러나 find
원하는 모든 작업을 수행 할 수없고 그 위치에 xargs
도달 하는 경우 가 있습니다.이 -exec
명령은 하나의 {}
나타나는 인스턴스 만 허용 하므로 오류가 find -type f -exec cp {} {}.bak \;
발생하면 대신 그렇게 할 수 있습니다. :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
GNU Findutils 매뉴얼 에서 Run Commands 에 대해 더 배울 수 있습니다 .
또한 find
파일을 처리 할 때 공백이나 다른 문자가 발생 xargs
하기 때문에 대신 null 옵션으로 끝나는 입력 항목을 생성하는 항목과 함께 -0
또는 --null
옵션 을 사용하지 않으면 문제가 발생할 수 있기 때문에 원하는 것을 안전하게 수행 한다고 언급했습니다. 공백.
'
있거나 "
문제가 될 수 있지만 문제가 find
없는 경우를 처리합니다.
xargs
(함께 find
, sort
, du
, uniq
, perl
및 일부 기타) "STDIN NUL은 (0 × 00) 바이트에 의해 분리 된 파일의리스트를 갖는다」라고하는 명령 줄 스위치를 수용한다. 따라서 공백과 기타 재미있는 문자가 포함 된 파일 이름을 쉽게 처리 할 수 있습니다. 파일 이름에 NUL이 포함되어 있지 않습니다.
xargs
및$(...)
) 으로 스트림을 가져 오는 두 가지 일반적인 옵션 중에서 xargs는 명령 대체보다 훨씬 안전합니다. 그리고 줄 바꿈이있는 합법적 인 파일 이름을 발견 한 것을 기억할 수 없습니다. 이스케이프 및 단어 확장 함정이 xargs가 아닌 명령 대체와 관련이 있습니까?