Вы можете взглянуть на файл /root/anaconda -ks.cfg. Это лучше объясненный ответ:
Попробуйте это,
grep -r abcd | awk -F ':' '{gsub(/.*\//,"",$1) }1' | awk '!seen[$1]++'
gsub
удалит структуру каталогов. (/.*\//,"",$1)
удалит ("" )все (. *)перед последним совпадением '/' в первом поле ($1 ). !seen[$1]++
будет уникальным для имени файла. Примечание. В имени каталога :не должно быть :
.
Я думаю, что со стандартными возможностями grep
это невозможно сделать.
Вы можете использовать что-то вроде этого, это просто "маленькое" регулярное выражение:
grep -r asdf | sed '#^.*/##' | sort --unique
Примечание. :Этот подход не будет работать, если шаблон поиска -содержит/
Эта группировка по базовому имени и выводу 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
из-за подвыражения ()и |
из-за косой черты.
Подвыражение (.*:)
немного простое (завершится ошибкой, если grepped строка содержит двоеточие ). Если вы пропустите двоеточие, произойдет сбой, если строка содержит косую черту.
Глядя на этот вывод, я говорю что это невозможно теоретически (анализировать вывод 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>
С perl -pe 's|.*?([^/]*:)|\1|'
кажется, что он работает с двоеточием и косой чертой в содержимом файлов (, а не в имени! ). Две строки ниже имеют оба.
]# grep -r ':' include |head -n3 | perl -pe 's|.*?([^/]*:)|\1|'
cistpl.h:/* SPDX-License-Identifier: GPL-2.0-only */
ss.h:/* SPDX-License-Identifier: GPL-2.0-only */
ss.h: * are three options:
Изгибается ли этот ум -? Идея кажется простой:
Сохраняйте все не-символы косой черты перед первым двоеточием.
Регулярное выражение |.*?([^/]*:)|
имеет следующие части:
.*?
соответствует чему угодно, но как можно меньше , тогда... ([^/]*:)
это подвыражение, которое... [^/]*:
как можно больше без -косой черты , а затем двоеточие. По крайней мере, он гнется в правильном направлении.
С выводом из 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