다음과 같은 줄이 있습니다.
find /foo/bar -name '*.mp4' -print0 | xargs -i {} -0 mv -t /some/path {}
하지만 다음과 같은 오류가 발생합니다.
xargs: argument line too long
혼란스러워요. Should를 사용하면 xargs
이 문제를 해결하는 데 도움이 될 수 있을까요 ?
노트:기술적으로 find를 사용할 수 있다는 것을 알고 있지만 -exec
위의 방법이 실패한 이유를 알고 싶습니다. xargs
입력을 작업 매개변수에 맞게 관리 가능한 크기로 분할하는 방법을 알아야 하기 때문입니다. 이것이 사실이 아닌가?
그것은 모두 zsh에 관한 것입니다.
답변1
우선 이 -i
스위치는 더 이상 사용되지 않습니다.
-i[replace-str]
This option is a synonym for -Ireplace-str if replace-str is specified.
If the replace-str argument is missing, the effect is the same as -I{}.
This option is deprecated; use -I instead.
그래서 귀하의 명령을 이것으로 변경했을 때 작동했습니다.
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
예
$ find . -print0 | xargs -I{} -0 echo {}
.
./.sshmenu
./The GIT version control system.html
./.vim_SO
./.vim_SO/README.txt
./.vim_SO/.git
./.vim_SO/.git/objects
./.vim_SO/.git/objects/pack
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.idx
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.pack
./.vim_SO/.git/objects/info
./.vim_SO/.git/refs
./.vim_SO/.git/refs/tags
...
사용-I{}
이 명령 구성을 실행한 이후에는 이 방법을 사용하면 안 됩니다.
$ find -print0 ... | xargs -I{} -0 ...
xargs
, -x
및 에 대해 이러한 스위치를 암시적으로 켭니다 -L 1
. 단일 방식으로 파일을 실행하려는 명령을 호출하도록 구성하십시오 -L 1
.xargs
xargs
따라서 1000개의 파일을 제공하면 mv
명령이 1000번 실행되기 때문에 여기서 사용하는 목적이 무산됩니다 .
그러면 어떤 방법을 사용해야 할까요?
다음과 같이 xargs를 사용하여 이 작업을 수행할 수 있습니다.
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
아니면 그냥 모두 찾아보세요:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
답변2
이 옵션은 -i
선택적 매개변수를 사용합니다. 뒤에 공백을 넣었기 때문에 -i
옵션에는 인수가 없으므로 -i
후속 옵션은 6개의 피연산자 중 두 번째가 아니라 6개의 피연산자 중 두 번째 -0
입니다 .xargs
{} -0 mv -t /some/path {}
options 만 사용하는 경우 -i
xargs는 개행으로 구분된 파일 이름 목록을 기대합니다. 입력에 개행 문자가 없을 수 있으므로 xargs는 커 보이는 파일 이름을 받습니다(널 바이트가 포함되어 있지만 xargs는 이를 확인하지 않음). 전체 출력을 포함하는 단일 문자열이 find
최대 명령줄 길이보다 길어서 "명령줄이 너무 깁니다"라는 오류가 발생합니다.
명령은 -i{}
대신 을 사용합니다 -i {}
. 또는 -I {}
: -I
과 유사 -i
하지만 필수 인수를 사용하여 에 전달된 다음 인수가 xargs
옵션에 대한 인수로 사용됩니다 -I
. 그러면 다음 매개변수가 -0
옵션으로 해석됩니다.
그러나 -I {}
전혀 사용해서는 안됩니다. 사용에는 -I
세 가지 기능이 있습니다.
-I
견적 처리를 닫으면-0
완료됩니다.-I
바꿀 문자열을{}
기본값으로 변경합니다.-I
명령이 각 입력 레코드에 대해 개별적으로 실행되도록 합니다. 이는 명령(mv -t
)이 호출당 여러 파일을 처리하도록 특별히 설계되었기 때문에 여기서는 쓸모가 없습니다.
포기 -I
하거나 -i
완전히
find /foo/bar -name '*.mp4' -print0 | xargs -0 mv -t /some/path {}
또는 xargs를 제거하고 다음을 사용하십시오 -exec
.
find /foo/bar -name '*.mp4' -exec mv -t /some/path {} +
답변3
bash for 루프를 사용해 보세요:
for FILE in *.mp4 ; do rm $FILE ; done
또는 무슨 일이 일어나고 있는지 확인하려면 다음을 수행하세요.
for FILE in *.mp4 ; do echo Removing $FILE ; rm $FILE ; done
답변4
사용 중에 이 내용을 본다면생선 껍질.
이는 물고기가 교체용 줄을 확장하는 방식과 관련이 있습니다.{}
Fish를 사용하는 경우 대체 문자열을 이스케이프 처리해야 합니다.\{\}
| xargs -I \{\} echo \{\}
또는 다른 대체 문자열을 사용하십시오.
| xargs -I ! echo !