[shell] xargs가 공백이 포함 된 파일 이름을 처리하도록 설정

$ ls *mp3 | xargs mplayer  

Playing Lemon.  
File not found: 'Lemon'  
Playing Tree.mp3.  
File not found: 'Tree.mp3'  

Exiting... (End of file)  

“Lemon Tree.mp3″파일에 공백이 포함되어 있으므로 xargs는 두 파일이라고 생각하기 때문에 명령이 실패합니다. find + xargs가 이와 같은 파일 이름으로 작동하도록 할 수 있습니까?



답변

xargs명령은 공백 문자 (탭, 공백, 줄 바꾸기)를 구분 기호로 사용합니다. 다음과 -d같은 옵션 을 사용하여 줄 바꾸기 문자 ( ‘\ n’)에 대해서만 범위를 좁힐 수 있습니다 .

ls *.mp3 | xargs -d '\n' mplayer

GNU xargs에서만 작동합니다. BSD 시스템의 경우 다음 -0과 같은 옵션을 사용하십시오 .

ls *.mp3 | xargs -0 mplayer

이 방법은 더 간단하며 GNU xargs에서도 작동합니다.


답변

xargs 유틸리티는 표준 입력에서 공백, 탭, 줄 바꾸기 및 파일 끝으로 구분 된 문자열을 읽고 문자열을 인수로 사용하여 유틸리티를 실행합니다.

공백을 구분 기호로 사용하지 않으려 고합니다. 이는 xargs의 분리 문자를 변경하여 수행 할 수 있습니다. 매뉴얼에 따르면 :

 -0      Change xargs to expect NUL (``\0'') characters as separators,
         instead of spaces and newlines.  This is expected to be used in
         concert with the -print0 function in find(1).

같은 :

 find . -name "*.mp3" -print0 | xargs -0 mplayer

일곱 번째 mp3 재생에 관한 질문에 대답하기 위해; 실행하는 것이 더 간단합니다

 mplayer "$(ls *.mp3 | sed -n 7p)"


답변

시험

find . -name \*.mp3 -print0 | xargs -0 mplayer

대신에

ls | grep mp3 


답변

MacOS의 xargs에는 -d 옵션이 없으므로이 솔루션은 대신 -0을 사용합니다.

ls가 한 줄에 하나의 파일을 출력하도록 한 다음 개행을 널로 변환하고 xargs에 널을 분리 문자로 사용하도록 지시하십시오.

ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer


답변

find . -name 'Lemon*.mp3' -print0 | xargs 0 -i mplayer '{}' 

이것은 내 경우 공백이있는 다른 파일을 삭제하는 데 도움이되었습니다. mplayer에서도 작동합니다. 필요한 트릭은 따옴표입니다. (Linux Xubuntu 14.04 에서 테스트되었습니다 .)


답변

Dick.Guertin의 답변 [1]은 파일 이름에서 공백을 이스케이프 처리 할 수있는 방법이 여기에 제안 된 다른 솔루션을 대체 할 수있는 귀중한 대안이라고 제안했습니다 (예 : 공백 대신 null 문자를 구분 기호로 사용). 그러나 더 간단 할 수 있습니다-당신은 정말로 독특한 캐릭터가 필요하지 않습니다. sed는 이스케이프 된 공백을 직접 추가 할 수 있습니다.

ls | grep ' ' | sed 's| |\\ |g' | xargs ...

또한 grep은 이름에 공백이있는 파일 원하는 경우에만 필요 합니다. 더 일반적으로 (예를 들어, 공백이있는 파일을 처리 할 때 일부는 공백이 아닌 경우) grep을 건너 뛰십시오.

ls | sed 's| |\\ |g' | xargs ...

그런 다음 파일 이름에 공백이 아닌 다른 공백 (예 : 탭)이있을 수 있습니다.

ls | sed -r 's|[[:blank:]]|\\\1|g' | xargs ...

즉, GNU sed 또는 최신 버전의 bsd sed와 같은 -r (확장 정규식)을 지원하는 sed가 있다고 가정합니다 (예 : FreeBSD 8 이전에 “-E”옵션의 철자를 사용한 FreeBSD와 호환성을 위해 -r & -E 모두 지원) 적어도 FreeBSD 11을 통해). 그렇지 않으면 기본 정규식 문자 클래스 대괄호 표현식을 사용하고 []구분 기호 에 공백과 탭 문자를 수동으로 입력 할 수 있습니다 .

[1]이 답변에 대한 의견이나 수정 사항으로 더 적합 할 수도 있지만 현재로서는 의견을 평가할만한 충분한 평판이 없으며 수정 사항 만 제안 할 수 있습니다. 후자의 형태는 (그렙없이) Dick.Guertin의 원래 답변을 변경하기 때문에 직접 편집하는 것은 적절하지 않습니다.


답변

ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}

위 명령 에서 각 파일에 대해 새로 xargs호출 mplayer합니다. 이는 바람직하지 mplayer않지만 다른 대상에는 적합 할 수 있습니다.