grep -r (рекурсивно), удалить/скрыть все каталоги

grep -r (рекурсивно), удалить/скрыть все каталоги

Нуб здесь - я хочу бежать grep -r asdf, однако,Мне нужны только уникальные совпадения в моих каталогах(т.е., игнорируя любой каталог, отображать только уникальные совпадения).

Итак, я запустил grep -r asdf | sort --unique. Однако - это не работает, так как имена каталогов разные ( dir1/a.txt asdfи dir2/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 не будет работать правильно. Регулярное выражение сначала отбрасывает все до последнего /, затем сохраняет все до a :как \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. Одна полная строка в одном include-файле выглядит так.

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

решение4

При использовании выходных данных grep --nullследующая awkпрограмма GNU должна работать с любым именем файла:

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

Связанный контент