xargs를 사용하여 여러 패턴을 잡기


12

grep하려는 용어가있는 파일이 있으며 각 용어는 파일에서 한 줄입니다. 나는 xargs로 이것을 할 수 있다고 생각했다. 이처럼 맨 페이지의 예제에서 얻을 수있는 것

find ./work -print0 | xargs -0 rm

xargs는 pre-pipe 명령의 출력을 인수 끝에 추가합니다. 따라서 찾기가 반환 report.doc되면 xargs가 생성 rm report.doc됩니다. 이 이해가 맞습니까?

따라서 파일의 값이 grep 명령의 중간에 오도록하려면 자리 표시자를 지정해야합니다. 놀면서, 시도 {}했지만 작동하지 않았습니다.

$> cat strings.txt | xargs grep {} subdirectory/*
grep: string1: No such file or directory
grep: string2: No such file or directory

xargs가 올바른 도구입니까? 그렇다면 구문은 무엇입니까?

답변:


17

네, find ./work -print0 | xargs -0 rm뭔가를 실행합니다 rm ./work/a "work/b c" .... 로 확인할 수 있으며 echo, find ./work -print0 | xargs -0 echo rm실행될 명령을 인쇄합니다 (공백이 echo표시되지는 않지만 적절하게 이스케이프 되지는 않습니다).

얻으려면 xargs중간에 이름을 넣어, 당신은 추가해야 할 -I[string]경우, [string]당신은 당신이 사용하는 거라고이 경우, 인수로 대체 할 것입니다 -I{}예를 들어, <strings.txt xargs -I{} grep {} directory/*.

실제로 사용하고 싶은 것은 grep -F -f strings.txt:

-F, --fixed-strings
  Interpret PATTERN as a  list  of  fixed  strings,  separated  by
  newlines,  any  of  which is to be matched.  (-F is specified by
  POSIX.)
-f FILE, --file=FILE
  Obtain  patterns  from  FILE,  one  per  line.   The  empty file
  contains zero patterns, and therefore matches nothing.   (-f  is
  specified by POSIX.)

따라서 grep -Ff strings.txt subdirectory/*모든 문자열을 strings.txt리터럴로 찾을 -F수 있습니다 . 옵션을 삭제 하면 파일에서 정규식을 사용할 수 있습니다. 실제로 사용할 수도 grep -F "$(<strings.txt)" directory/*있습니다. 연습하고 싶다면 find요약의 마지막 두 예제를 사용할 수 있습니다. 첫 번째 수준이 아닌 재귀 검색을 수행하려는 경우 요약에도 몇 가지 옵션이 있습니다.

요약:

# grep for each string individually.
<strings.txt xargs -I{} grep {} directory/*

# grep once for everything
grep -Ff strings.txt subdirectory/*
grep -F "$(<strings.txt)" directory/*

# Same, using file
find subdirectory -maxdepth 1 -type f -exec grep -Ff strings.txt {} +
find subdirectory -maxdepth 1 -type f -print0 | xargs -0 grep -Ff strings.txt

# Recursively
grep -rFf strings.txt subdirectory
find subdirectory -type f -exec grep -Ff strings.txt {} +
find subdirectory -type f -print0 | xargs -0 grep -Ff strings.txt

-l실제 줄을 볼 필요가없는 경우 옵션 을 사용하여 일치하는 각 파일의 이름 만 가져 오십시오.

-l, --files-with-matches
  Suppress  normal  output;  instead  print the name of each input
  file from which output would normally have  been  printed.   The
  scanning  will  stop  on  the  first match.  (-l is specified by
  POSIX.)

4

xargsfgrep일치하는 문자열 파일에 정규 표현식이 아닌 문자열 만 포함 된 경우 제안하는 최선의 도구가 아닐 수 있습니다 .

fgrep -f strings.txt subdirectory/*

내가 제안 fgrep전통적인 유닉스로 grepegrep은 "-f"옵션이 없었다. 나는 GNU를 생각 grep하고 egrep파일이 정규 표현식을 가지고 그렇다면, 당신은 GNU 버전을 사용하고 싶을은 "-f"옵션을해야합니까.

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