답변:
항상 그렇듯이주의하십시오 grep -r
. -r
는 표준 옵션이 아니며 최신 버전의 GNU와 같은 일부 구현 grep
에서는 디렉토리 트리를 내릴 때 기호 링크를 따릅니다. 일반적으로 원하는 것이 아니며 예를 들어 "/ 디렉토리 트리 어딘가에
유닉스 철학에서는 명령을 사용하여 디렉토리를 검색하여 파일을 찾고 다른 디렉토리를 찾아 내용을 봅니다.
GNU 도구를 사용하여 다음을 수행합니다.
xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
) mv -i --target-directory /dest/dir
그러나 다른 사용자가 쓸 수있는 디렉토리에서 한 사용자로 실행하는 경우 경쟁 조건 및 가능한 보안 문제에주의하십시오.
xargs
xargs 자체가 죽거나 어떤 이유로 든 실패하지 않으면 발생하지 않는 arg 파일의 끝을 읽기 전에 종료 된 경우에만 발생합니다.이 경우 에도 오류가 표시됩니다.
의 세 번째 구문 xargs
과 함께 사용하십시오 mv
.mv [OPTION]... -t DIRECTORY SOURCE...
grep -lir 'string' ~/directory/* | xargs mv -t DEST
특수 문자 (공백, 따옴표)가 포함 된 파일에주의하십시오. 이 경우 sed
(파일 이름 주위에 따옴표 추가)로 목록을 필터링하면 s/^/'/;s/$/'/
도움이 될 수 있지만 반드시 따옴표는 파일 이름에 나타나지 않습니다. GNU grep
에는 파일 이름을 NUL로 종료 하는 -Z
/ --null
옵션이 있습니다.
세 번째 구문의 대안 은 자리 표시 자 문자열 ( ) 과 함께 mv
사용 xargs
하는 것 -I
입니다.
또 다른 옵션은 ire_and_curses의 답변에 언급 된 명령 대체 $( )
또는 백틱 ``
(bash)입니다.
파일 이름에 특수 문자 (공백 또는 \[*?
)가 포함되어 있지 않으면 명령 대체를 사용하십시오 .
mv `grep -lir 'string' ~/directory/*` destination/
POSIX 지정 기능 만 사용 하고 파일 이름에 대한 가정은 없습니다 .
find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;
노트:
"패턴"이 아니라 "문자열"이라고 말 했으므로 -F
(고정 문자열 검색) 옵션이 grep
적절 해 보입니다.
대상 디렉토리가 검색 디렉토리 안에 있으면 불쾌한 경쟁 조건이있을 수 있습니다.
grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name