상황은 mpg321
파일 목록을 매개변수로 받아들이는 MP3 플레이어가 있다는 것입니다. 나는 "music"이라는 디렉터리에 내 음악을 저장했는데 그 안에 몇 개의 디렉터리가 있습니다. 그냥 다 가지고 놀고 싶어서 프로그램을 실행해봅니다
mpg321 $(find /music -iname "*\.mp3")
. 문제는 일부 파일 이름에 공백이 있고 프로그램이 이러한 이름을 더 작은 부분으로 나누고 파일 누락에 대해 불평한다는 것입니다. 결과를 find
따옴표로 묶습니다.
mpg321 "$(find /music -iname "*\.mp3")"
모든 것이 분명히 찾을 수 없는 하나의 큰 "파일 이름"으로 바뀌기 때문에 도움이 되지 않습니다.
어떻게 해야 하나요? 그게 중요하다면, 나는 그것을 사용하고 있지만 bash
곧 전환할 것입니다.zsh
답변1
-print0
다음과 같이 find's 또는 option을 조합하여 사용해 보십시오 .-printf
xargs
find /music -iname "*\.mp3" -print0 | xargs -0 mpg321
이것이 어떻게 작동하는지는 다음과 같이 설명됩니다.찾기 매뉴얼 페이지:
-0을 인쇄하세요.
True이면 표준 출력에 전체 파일 이름을 인쇄하고 그 뒤에 널 문자(-print에서 사용하는 개행 문자 대신)를 인쇄합니다. 이를 통해 find 출력을 처리하는 프로그램이 개행 또는 기타 유형의 공백이 포함된 파일 이름을 올바르게 해석할 수 있습니다. 이 옵션은 xargs의 -0 옵션에 해당합니다.
답변2
find /music -iname "*\.mp3" -exec mpg123 {} +
GNU find를 사용하면 다음을 사용할 수도 있습니다.-print0
그리고xargs -0
, 하지만 다른 도구를 배우는 데는 거의 의미가 없습니다. 이 -exec ... {} +
구문은 Linux에서 늦게 구현되었기 때문에 거의 언급되지 않지만 -print0
지금은 사용하지 않을 이유가 없습니다.
zsh 또는 bash 4를 사용하면 훨씬 간단합니다.
mpg123 **/*.[Mm][Pp]3
zsh에서만 (일부) 패턴을 대소문자를 구분하지 않게 만들 수 있습니다.
mpg123 (#i)**/*.mp3
답변3
제 생각에는스티븐의 솔루션가장 좋지만 또 다른 방법은 xargs -I
플래그를 사용하는 것입니다. 이를 통해 문자열을 지정한 다음 해당 문자열을 명령의 인수로 바꿀 수 있습니다(명령 끝에 인수를 추가하는 대신). 이를 사용하여 매개변수를 참조할 수 있습니다.
find /music -iname "*\.mp3" | xargs -0 -Ifoo mpg321 "foo"
답변4
또 다른 방법은 파일 이름에 나타나는 특수 문자를 이스케이프하는 것입니다. 예를 들어:
find /music -iname "*\.mp3" | sed 's!\([] \*\$\/&[]\)!\\\1!g' | xargs mpg321
이는 기본적으로 올바르게 이스케이프된 파일 이름을 xargs에 전달하여 문제 없이 실행됩니다.