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
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의 원래 답변을 변경하기 때문에 직접 편집하는 것은 적절하지 않습니다.
find . -name 'Lemon*.mp3' -print0 | xargs -0 -i mplayer '{}'
이것은 내 경우 공백이있는 다른 파일을 삭제하는 데 도움이되었습니다. mplayer에서도 작동합니다. 필요한 트릭은 따옴표입니다. (Linux Xubuntu 14.04 에서 테스트되었습니다 .)
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
위 명령 에서 각 파일에 대해 새로 xargs
호출 mplayer
합니다. 이는 바람직하지 mplayer
않지만 다른 대상에는 적합 할 수 있습니다.
macOS 10.12.x (Sierra)에서 파일 이름 또는 하위 디렉토리에 공백이 있으면 다음을 사용할 수 있습니다.
find . -name '*.swift' -exec echo '"{}"' \; |xargs wc -l
(a) 레몬과 달리 숫자 7에 어떻게 연결되어 있는지, (b) 파일 이름에 줄 바꿈이 포함되어 있는지 여부 및 파일 이름이 바뀌면 기꺼이 바꿀지 여부에 따라 다릅니다.
여러 가지 방법으로 처리 할 수 있지만 그 중 일부는 다음과 같습니다.
mplayer Lemon*.mp3
find . -name 'Lemon*.mp3' -exec mplayer {} ';'
i=0
for mp3 in *.mp3
do
i=$((i+1))
[ $i = 7 ] && mplayer "$mp3"
done
for mp3 in *.mp3
do
case "$mp3" in
(Lemon*) mplayer "$mp3";;
esac
done
i=0
find . -name *.mp3 |
while read mp3
do
i=$((i+1))
[ $i = 7 ] && mplayer "$mp3"
done
read
파일 이름이 개행 문자가 포함 된 경우 루프가 작동하지 않습니다; 다른 것들은 이름의 개행으로도 올바르게 작동합니다 (공백 제외). 내 돈을 위해 줄 바꿈이 포함 된 파일 이름이 있으면 줄 바꿈없이 파일 이름을 바꿔야합니다. 루프가 올바르게 작동하려면 파일 이름을 큰 따옴표로 묶어야합니다.
GNU find
및 GNU xargs
(또는 FreeBSD (* BSD?) 또는 Mac OS X)가있는 경우 다음 -print0
과 같이 및 -0
옵션을 사용할 수 있습니다 .
find . -name 'Lemon*.mp3' -print0 | xargs -0 mplayer
이름의 내용에 관계없이 작동합니다 (파일 이름에 표시 할 수없는 두 문자 만 슬래시와 NUL이며 슬래시는 파일 경로에 문제를 일으키지 않으므로 이름 구분 기호로 NUL을 사용하면 모든 것을 다룹니다). 그러나 처음 6 개 항목을 필터링 해야하는 경우 줄 바꿈 대신 NUL로 끝나는 '줄'을 처리하는 프로그램이 필요합니다 ... 그리고 확실하지 않습니다.
첫 번째는 현재 진행중인 특정 사례에서 가장 단순합니다. 그러나 아직 나열하지 않은 다른 시나리오는 다루지 않을 수 있습니다.
나는 xargs
질문에 직접 대답 하지는 않지만 find
의 -exec
옵션을 언급 할 가치가 있음을 알고 있습니다.
다음과 같은 파일 시스템이 제공됩니다.
[root@localhost bokeh]# tree --charset assci bands
bands
|-- Dream\ Theater
|-- King's\ X
|-- Megadeth
`-- Rush
0 directories, 4 files
find 명령은 Dream Theater와 King 's X의 공간을 처리하도록 만들 수 있습니다. 따라서 grep을 사용하여 각 밴드의 드러머를 찾으십시오.
[root@localhost]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
에서 -exec
옵션 {}
경로를 포함한 파일 이름을 의미합니다. 이스케이프하거나 따옴표로 묶을 필요는 없습니다.
-exec
종료 자 ( +
와 \;
) 의 차이점은 +
하나의 명령 줄에 가능한 많은 파일 이름을 그룹화한다는 것입니다. 반면 \;
각 파일 이름에 대한 명령을 실행합니다.
따라서 find bands/ -type f -exec grep Drums {} +
결과는 다음과 같습니다.
grep Drums "bands/Dream Theater" "bands/Rush" "bands/King's X" "bands/Megadeth"
find bands/ -type f -exec grep Drums {} \;
결과는 다음 과 같습니다.
grep Drums "bands/Dream Theater"
grep Drums "bands/Rush"
grep Drums "bands/King's X"
grep Drums "bands/Megadeth"
이 경우 grep
파일 이름 인쇄 여부에 따른 부작용이 있습니다.
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} \;
Drums:Mike Mangini
Drums: Neil Peart
Drums:Jerry Gaskill
Drums:Dirk Verbeuren
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
물론, grep
'옵션을이야 -h
와 -H
파일 이름에 관계없이 어떻게 인쇄할지 여부를 제어합니다 grep
라고합니다.
xargs
xargs
명령 행에서 man 파일이있는 방법을 제어 할 수도 있습니다.
xargs
기본적으로 모든 인수는 한 줄로 그룹화됩니다. -exec \;
사용 하는 것과 동일한 작업을 수행합니다 xargs -l
. 이 -t
옵션은 xargs
명령을 실행하기 전에 인쇄하도록 지시 합니다.
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -l -t grep Drums
grep Drums ./bands/Dream Theater
Drums:Mike Mangini
grep Drums ./bands/Rush
Drums: Neil Peart
grep Drums ./bands/King's X
Drums:Jerry Gaskill
grep Drums ./bands/Megadeth
Drums:Dirk Verbeuren
이 -l
옵션은 xargs가 모든 파일 이름에 대해 grep을 실행하도록 지시합니다.
기본값 대 ( -l
옵션 없음 ) :
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush ./bands/King's X ./bands/Megadeth
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
xargs
명령 줄에 몇 개의 파일이 있는지 더 잘 제어 할 수 있습니다. -l
옵션 당 명령 당 최대 파일 수를 제공하십시오 .
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -l2 -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
grep Drums ./bands/King's X ./bands/Megadeth
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
[root@localhost bokeh]#
이 grep
때문에 두 개의 파일 이름으로 실행 되었음을 참조하십시오 -l2
.
이 게시물의 특정 제목을 감안할 때 다음은 내 제안입니다.
ls | grep ' ' | tr ' ' '<' | sed 's|<|\\ |g'
아이디어는 공백을 '<'와 같은 고유 문자로 변환 한 다음 백 슬래시와 공백을 '\'로 변경하는 것입니다. 그런 다음 다음과 같이 원하는 명령으로 파이프 할 수 있습니다.
ls | grep ' ' | tr ' ' '<' | sed 's|<|\\ |g' | xargs -L1 GetFileInfo
여기서 핵심은 'tr'및 'sed'명령에 있습니다. '?'와 같이 '<'이외의 문자를 사용할 수 있습니다. 또는 탭 문자.
대체 솔루션이 도움이 될 수 있습니다 ...
Perl을 사용하여 줄 끝에 널 문자를 추가 한 다음 -0
xargs 의 옵션 을 사용할 수도 있습니다. xargs -d '\ n'(승인 된 답변)과 달리 이것은 OS X를 포함한 모든 곳에서 작동합니다.
예를 들어 공백이나 다른 재미있는 문자가 포함될 수있는 JPEG 이미지를 재귀 적으로 나열 (실행, 이동 등)하려면 다음을 사용합니다.
find . | grep \.jpg | perl -ne 'chop; print "$_\0"' | xargs -0 ls
(참고 : 필터링의 경우 "find 's"--name 인수보다 기억하기 쉬운 "| grep"구문을 선호합니다.
참고 URL : https://stackoverflow.com/questions/16758525/make-xargs-handle-filenames-that-contain-spaces
'Programing' 카테고리의 다른 글
Nodejs가 Windows에서 설치된 모듈을 찾을 수 없습니다 (0) | 2020.04.18 |
---|---|
Gulp 설치 후 : "gulp '명령이 없습니다" (0) | 2020.04.18 |
Git의 다른 지점에있는 지점 인 '병합'이 아닌 '덮어 쓰기'는 어떻게합니까? (0) | 2020.04.18 |
HTML에서 공백 무시 (0) | 2020.04.18 |
"참조 된 어셈블리에 강력한 이름이 없습니다"오류를 수정하는 방법? (0) | 2020.04.18 |