[linux] xargs를 사용하여 이름에 공백과 인용 부호가있는 파일을 복사하려면 어떻게합니까?


Answers

find . -print0 | grep --null 'FooBar' | xargs -0 ...

grep--null 지원 --null , xargs 가 Leopard에서 -0 지원하는지 여부는 모르지만 GNU에서는 모두 좋습니다.

Question

나는 디렉토리 아래에있는 파일들을 복사하려고 시도하고있다. 그리고 그 파일들의 수는 그들의 이름에 공백과 작은 따옴표를 가지고있다. 함께 xargs find grep 하려고하면 다음 오류가 발생합니다.

find .|grep "FooBar"|xargs -I{} cp "{}" ~/foo/bar
xargs: unterminated quote

xargs의보다 강력한 사용에 대한 제안?

이것은 MacOS 10.5.3에서 BSD xargs 입니다.




다른 대답에서 논의 된 대부분의 옵션은 GNU 유틸리티 (예 : Solaris, AIX, HP-UX)를 사용하지 않는 플랫폼에서는 표준이 아닙니다. '표준'xargs 동작에 대해서는 POSIX 사양을 참조하십시오.

xargs의 동작은 입력이 없더라도 명령을 적어도 한 번 실행하면 불쾌하다고 생각합니다.

나는 이름에서 공백의 문제를 다루기 위해 xargs (xargl)의 개인용 버전을 작성했습니다 (새 줄만 분리합니다 - 'find ... -print0'및 'xargs -0'조합은 파일 이름을 사용할 수 없다는 점을 감안할 때 상당히 깔끔합니다). ASCII NUL '\ 0'문자가 포함되어 있습니다. xargl은 퍼블리싱 할 가치가 있어야 할만큼 완벽하지는 않습니다 - 특히 GNU는 최소한 좋은 기능을 갖추고 있습니다.




bash를 사용하고 있다면, stdoutmapfile 에 의해 행의 배열로 변환 할 수 있습니다.

find . | grep "FooBar" | (mapfile -t; cp "${MAPFILE[@]}" ~/foobar)

이점은 다음과 같습니다.

  • 내장되어있어 더 빠릅니다.
  • 한 번에 모든 파일 이름으로 명령을 실행하십시오.
  • 파일 이름에 다른 인수를 추가 할 수 있습니다. cp 경우 다음 작업을 수행 할 수도 있습니다.

    find . -name '*FooBar*' -exec cp -t ~/foobar -- {} +
    

    그러나 일부 명령에는 이러한 기능이 없습니다.

단점 :

  • 파일 이름이 너무 많으면 확장되지 않을 수 있습니다. (한계는 모르겠지만 데비안에서는 문제없이 10000 개 이상의 파일 이름을 포함하는 10MB 목록 파일로 테스트했습니다)

음 ... 누가 OS X에서 bash를 사용할 수 있는지 알고 있습니까?




나는 대부분의 문제를 해결하는 "xargs"주위에 "xargsL"이라는 작은 휴대용 래퍼 스크립트를 만들었습니다.

xargs와 달리 xargsL은 한 행에 하나의 경로 이름을 허용합니다. 경로명은 (분명히) 개행 문자 또는 NUL 바이트를 제외한 문자를 포함 할 수 있습니다.

파일명에는 공백, 백 슬래시, 백틱, 쉘 와일드 카드 문자 등이 포함될 수 있습니다. xargsL은 문자 그대로 리터럴 문자로 처리합니다. 아무런 해를 입지 않습니다.

추가 보너스 기능으로 xargsL은 입력이 없으면 명령을 한 번 실행 하지 않습니다 !

차이점에 유의하십시오.

$ true | xargs echo no data
no data

$ true | xargsL echo no data # No output

xargsL에 주어진 인수는 xargs로 전달됩니다.

다음은 "xargsL"POSIX 쉘 스크립트입니다 :

#! /bin/sh
# Line-based version of "xargs" (one pathname per line which may contain any
# amount of whitespace except for newlines) with the added bonus feature that
# it will not execute the command if the input file is empty.
#
# Version 2018.76.3
#
# Copyright (c) 2018 Guenther Brunthaler. All rights reserved.
#
# This script is free software.
# Distribution is permitted under the terms of the GPLv3.

set -e
trap 'test $? = 0 || echo "$0 failed!" >& 2' 0

if IFS= read -r first
then
        {
                printf '%s\n' "$first"
                cat
        } | sed 's/./\\&/g' | xargs ${1+"$@"}
fi

$ PATH의 어떤 디렉토리에 스크립트를 넣고 잊지 마라.

$ chmod +x xargsL

스크립트를 실행 가능하게 만듭니다.




이 방법은 Mac OS X Lion 10.7.5에서 작동합니다.

find . | grep FooBar | xargs -I{} cp {} ~/foo/bar

편집 : 또한 방금 게시 한 정확한 구문을 테스트했습니다. 10.7.5에서도 잘 돌아갔습니다.




솔라리스에서 약간 변형 된 Bill Star의 답변을 사용했습니다.

find . -mtime +2 | perl -pe 's{^}{\"};s{$}{\"}' > ~/output.file

그러면 각 행 주위에 따옴표가 붙습니다. 아마도 도움이 되겠지만 '-l'옵션을 사용하지 않았습니다.

내가 가고있는 파일 목록에는 줄 바꿈이 아닌 '-'이있을 수 있습니다. xargs를 통해 대량으로 삭제하기 전에 발견 된 내용을 검토하기 위해 다른 명령과 함께 출력 파일을 사용하지 않았습니다.




다음과 같이 Foobar 디렉토리를 grep해야 할 수도 있습니다.

find . -name "file.ext"| grep "FooBar" | xargs -i cp -p "{}" .



find에서 -print0 옵션을 사용하여 xargs에 --null 명령 행 옵션을 사용하십시오.




나는 다음 구문이 나를 위해 잘 작동한다는 것을 발견했다.

find /usr/pcapps/ -mount -type f -size +1000000c | perl -lpe ' s{ }{\\ }g ' | xargs ls -l | sort +4nr | head -200

이 예제에서는 "/ usr / pcapps"에 마운트 된 파일 시스템에서 1,000,000 바이트가 넘는 가장 큰 200 개의 파일을 찾고 있습니다.

"find"와 "xargs"사이의 Perl 라인 라이너는 각 공백을 이스케이프 / 쿼트하므로 "xargs"는 공백이있는 파일 이름을 단일 인수로 "ls"로 전달합니다.

Bill Starr Fri, 2009 년 1 월 23 일 5:40 pm EST




원래 포스터가 원하는 것을 수행하는 가장 쉬운 방법은 구분 기호를 공백 문자에서 다음과 같이 줄 끝 문자로 변경하는 것입니다.

find whatever ... | xargs -d "\n" cp -t /var/tmp



이 작업을 조금 해보고 xargs 수정을 고려하기 시작했습니다. 여기서 말하는 유즈 케이스의 경우 파이썬에서 간단한 구현이 더 좋은 아이디어라는 것을 깨달았습니다. 한 가지는 80 줄 정도의 코드를 사용하는 것이 무엇이 진행되고 있는지 파악하기 쉽다는 것이며, 다른 동작이 필요한 경우에는 새로운 스크립트로 해킹하는 것보다 짧은 시간에 새 스크립트를 해킹 할 수 있다는 것입니다 어딘가에 같은 응답.

https://github.com/johnallsup/jda-misc-scripts/blob/master/yargshttps://github.com/johnallsup/jda-misc-scripts/blob/master/zargs.py

작성된 yargs (및 python3이 설치되어 있음)를 입력하면

find .|grep "FooBar"|yargs -l 203 cp --after ~/foo/bar

한 번에 203 개의 파일을 복사 할 수 있습니다. (여기서 203은 물론 자리 표시 자일 뿐이며 203과 같은 이상한 번호를 사용하면이 번호가 다른 의미가 없음을 분명히 알 수 있습니다.)

파이썬을 필요로하지 않고 더 빠른 것을 원한다면 zargs와 yargs를 프로토 타입으로 사용하고 C ++이나 C로 다시 작성하십시오.




Related