xargs는 언제 필요합니까? xargs명령은 항상 혼란스러워합니다. 그것에 대한

xargs명령은 항상 혼란스러워합니다. 그것에 대한 일반적인 규칙이 있습니까?

아래 두 가지 예를 고려하십시오.

$ \ls | grep Cases | less

‘Cases’와 일치하는 파일을 인쇄하지만 명령을 변경 touch하려면 xargs다음 이 필요합니다 .

$ \ls | grep Cases | touch
touch: missing file operand
Try `touch --help' for more information.

$ \ls | grep Cases | xargs touch



답변

차이점은 대상 프로그램이 수용하는 데이터에 있습니다.

파이프 만 사용하는 경우 STDIN (표준 입력 스트림)의 데이터를 한 번에 한 줄씩 정렬 할 수있는 원시 데이터 더미로 수신합니다. 그러나 일부 프로그램은 표준으로 명령을 수락하지 않으며 명령에 대한 인수에서 철자를 기대합니다. 예를 들어 touch, 명령 행에서 다음과 같이 파일 이름을 매개 변수로 사용합니다 touch file1.txt.

당신은 파일 이름을 출력하는 프로그램이 있으면 밖으로 표준을 하고 사용하려는 인자로touch, 당신은 사용해야하는 xargs표준 입력 스트림 데이터를 읽고 명령을 공백으로 구분 인수로 각 라인을 변환한다.

이 두 가지는 동일합니다.

# touch file1.txt
# echo file1.txt | xargs touch

xargs정확히 무엇을하고 있고 왜 필요한지 알지 않는 한 사용 하지 마십시오 . xargs변환을 강제하는 데 사용 하는 것보다 작업을 수행하는 더 좋은 방법이있는 경우가 종종 있습니다. 변환 과정에는 탈출과 단어 확장 등과 같은 잠재적 인 함정이 있습니다.


답변

이미 제공된 답변을 확장하려면 xargs오늘날의 멀티 코어 및 분산 컴퓨팅 환경에서 점점 중요 해지고있는 멋진 일을 처리 할 수 ​​있습니다. 프로세스 작업을 병렬 처리 할 수 ​​있습니다.

예를 들면 다음과 같습니다.

$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8

한 번에 세 개의 프로세스를 사용하여 * .wav => * .flac를 인코딩합니다 ( -P 3).


답변

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 | lessls및에서 생성 한 파일 이름 목록을 찾아 볼 수 있습니다 grep. 파일 이름이 중요하지는 않지만 텍스트 일뿐입니다.

\ls | grep Cases | xargs less명령의 첫 부분에서 이름이 생성 된 파일을 찾아 볼 수 있습니다. xargs입력 및 명령 줄에서 명령으로 파일 이름의 목록을 받아,의 파일 이름으로 명령을 실행 명령 행.

사용을 고려하는 경우 xargs에, 공백으로 구분 : 그것은 이상한 방식으로 서식 입력 기대하는 마음에 계속 \, '그리고 "(때문에 비정상적인 방법으로 인용 부호를 사용 \하지 특수 내부 인용 부호)입니다. xargs파일 이름에 공백이나가 포함되지 않은 경우 에만 사용 하십시오 \'".


답변

귀하의 예에서는 원하는 것을 정확하고 안전하게 수행 할 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옵션 을 사용하지 않으면 문제가 발생할 수 있기 때문에 원하는 것을 안전하게 수행 한다고 언급했습니다. 공백.


답변

xargs(함께 find, sort, du, uniq, perl및 일부 기타) “STDIN NUL은 (0 × 00) 바이트에 의해 분리 된 파일의리스트를 갖는다」라고하는 명령 줄 스위치를 수용한다. 따라서 공백과 기타 재미있는 문자가 포함 된 파일 이름을 쉽게 처리 할 수 ​​있습니다. 파일 이름에 NUL이 포함되어 있지 않습니다.


답변