grep -r (재귀), 모든 디렉토리 삭제/숨기기

grep -r (재귀), 모든 디렉토리 삭제/숨기기

여기 멍청한 놈 - 난 여기서 멍청한 놈을 운영하고 싶지만 grep -r asdf- 하지만내 디렉터리에 고유한 일치 항목만 원합니다.(즉, 모든 디렉터리를 무시하고 고유한 일치 항목만 표시합니다.)

그래서 나는 달렸다 grep -r asdf | sort --unique. 하지만 - 디렉토리 이름이 다르기 때문에( dir1/a.txt asdfdir2/a.txt asdf) 작동하지 않습니다.

디렉토리를 제외하는 옵션이 표시되지 않습니다 grep -riol(예를 들어 시도했습니다). 이는 기능의 범위에 거의 의미가 없는 것 같습니다. 어떻게든 디렉토리를 잘라내어 일치하는 파일 이름 + 일치 항목만 표시할 수 있습니까(아마도 마음/유니버스 벤딩 정규식/sed/... 없이)?

답변1

grep기본 기능을 사용하면 이것이 가능하지 않다고 생각합니다 .

"작은" 정규식인 다음과 같은 것을 사용할 수 있습니다.

grep -r asdf | sed '#^.*/##' | sort --unique

참고: 검색 패턴에 다음이 포함된 경우/

답변2

이 시도,

grep -r abcd | awk -F ':' '{gsub(/.*\//,"",$1) }1' | awk '!seen[$1]++'
  • gsub디렉터리 구조가 제거됩니다. (/.*\//,"",$1)첫 번째 필드($1)에서 '/'가 마지막으로 일치하기 전의 모든(.*)이 삭제됩니다.
  • !seen[$1]++파일 이름을 고유하게 지정합니다.

:참고: 디렉터리 이름에는 포함될 수 없습니다.

답변3

이는 기본 이름과 grep 출력별로 그룹화됩니다.

   ]# grep -ro '#include' include/ |sed -E 's|.*/(.*:)|\1|' |uniq -c |sort|tail -n7
         28 kvm_host.h:#include
         28 mm.h:#include
         29 ib_verbs.h:#include
         31 net_namespace.h:#include
         32 sock.h:#include
         44 fs.h:#include
         48 drmP.h:#include

나는 중복된 것을 얻곤 했습니다 grep -o. 또한 슬래시가 생략되었습니다 ...

이름에 :sed가 포함되어 있으면 제대로 작동하지 않습니다 . 정규식은 먼저 끝까지 모든 것을 버린 /다음 까지의 모든 :것을 \1.

나는 -E이유(하위 표현식)와 |슬래시를 사용합니다.


하위 표현식은 (.*:)좀 더 간단합니다(행에 콜론이 포함되어 있으면 grep이 실패합니다). 콜론을 생략하면 줄에 슬래시가 포함되어 있으면 실패합니다.


이 출력을 보면서 나는 말했다.그건 말도 안 돼이론적으로(이 방법으로 grep의 출력을 구문 분석합니다):

]# grep -r "" d*
d:/ir:/afile...in file "d"
d:/ir:/afile...in file "ir"

그것은 동일합니다.끝에 콜론이 있는 디렉터리와 이름과 내용이 겹치는 파일이 필요합니다.

]# ls d* 
d

'd:':
ir

grep --color달라져라!


include디렉터리는 Linux 커널 소스 코드의 디렉터리입니다. 포함 파일의 전체 줄은 다음과 같습니다.

]# grep -rH '#incl' include/linux/aio.h 
include/linux/aio.h:#include <linux/aio_abi.h>

답변4

전달된 출력 grep --null, 다음 GNU awk프로그램은 모든 파일 이름에서 작동해야 합니다.

BEGIN {
    # OFS will be printed between
    # each filename and matched line
        OFS = ":"

    # Use null-byte as a record separator
    # to use with output from grep --null
        RS = "\0"

    # Apart from the first record,
    # everything up to the first newline
    # of a record is the matched line from grep
    # Everything after first newline is a filename
        FPAT = "^[^\n]*|\n.*$"

}
NR == 1 {
    # Entire first record
    # is the first filename
    # set `file` to the basename
        file = gensub(".*/","",1)
        next
}
! seen[file, $1]++ {
    # If filename+match
    # not seen, print it
        print file, $1
}
{
    # Get basename of file
    # from next match
        file = gensub(".*/","",1,$2)
}

grep --null -rF asdf . | awk -f see_above.gawk

관련 정보