텍스트 문자열이 포함 된 파일을 찾아 이동하는 Grep 명령


15

이 명령을 사용하여 특정 텍스트 문자열을 포함하는 폴더에서 파일을 찾을 수 있습니다.

grep -lir 'string' ~/directory/*

위 결과에 나타나는 파일을 다른 위치로 옮기려면 어떻게합니까?


여기있어. grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Alan Dong

답변:


10

항상 그렇듯이주의하십시오 grep -r. -r는 표준 옵션이 아니며 최신 버전의 GNU와 같은 일부 구현 grep에서는 디렉토리 트리를 내릴 때 기호 링크를 따릅니다. 일반적으로 원하는 것이 아니며 예를 들어 "/ 디렉토리 트리 어딘가에

유닉스 철학에서는 명령을 사용하여 디렉토리를 검색하여 파일을 찾고 다른 디렉토리를 찾아 내용을 봅니다.

GNU 도구를 사용하여 다음을 수행합니다.

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

그러나 다른 사용자가 쓸 수있는 디렉토리에서 한 사용자로 실행하는 경우 경쟁 조건 및 가능한 보안 문제에주의하십시오.


`grep '신호 13에 의해 종료되었습니다. 어떤 생각이 잘못 되었습니까?
Reena Parekh

@ReenaParekh는 SIGPIPE입니다. xargsxargs 자체가 죽거나 어떤 이유로 든 실패하지 않으면 발생하지 않는 arg 파일의 끝을 읽기 전에 종료 된 경우에만 발생합니다.이 경우 에도 오류가 표시됩니다.
Stéphane Chazelas

15

의 세 번째 구문 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)입니다.


3
gnu grep은 0 바이트 문자로 파일 이름을 구분하기 위해 -Z 플래그를 지원합니다. -0 플래그와 함께 xargs를 사용하면 언급 한 특수 문자 문제를 해결할 수 있습니다.
iruvar

@ChandraRavoori 감사합니다, 나는 대답을 업데이트했습니다.
peterph

7

파일 이름에 특수 문자 (공백 또는 \[*?)가 포함되어 있지 않으면 명령 대체를 사용하십시오 .

mv `grep -lir 'string' ~/directory/*` destination/

백틱은 더 이상 사용되지 않습니다. 보다 이식 가능하고 읽기 쉽고 스택 가능한 $ (...)를 대신 사용하십시오.
사용자가 알 수 없음

2

POSIX 지정 기능 만 사용 하고 파일 이름에 대한 가정은 없습니다 .

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

노트:

"패턴"이 아니라 "문자열"이라고 말 했으므로 -F(고정 문자열 검색) 옵션이 grep적절 해 보입니다.

대상 디렉토리가 검색 디렉토리 안에 있으면 불쾌한 경쟁 조건이있을 수 있습니다.

POSIX 사양 grep

POSIX 사양 find


이것은 Macos / BSD에서 가장 좋은 솔루션 일 수 있습니다
Ali

0

GNU 병렬 사용 :

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dong은 xargs로 자신의 원래 답변을 받았습니다.


1 년 전의 의견에 @lindong의 답변을 인정했다면 좋았을 것입니다.
roaima

0

대상 디렉토리가 '외부'이고 모든 XLS 파일을 이동해야한다고 가정하면 아래 명령을 시도 할 수 있습니다

sudo mv find /var/log/ -type f -name "*.xls"/ 외부 /

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.