Рецепт Жиля великолепен, но он не подходит для моих коммутаторов huawei 5720
но он работает после небольшой модификации
ssh-keygen -e -m pem -f ~/.ssh/id_rsa.pub | \
egrep -v "BEGIN|END" | base64 -d | \
od -t x1 -An -w4 | tr 'a-f' 'A-F' | tr -d ' ' | fmt -w 72
Я предполагаю, что вы исправили окончания строк в стиле -DOS, как обсуждалось в комментариях, и что searchFiles.txt
на самом деле не содержит пустых строк.
Тест -name
из find
использует только один шаблон имени файла. Шаблоны могут содержать символы оболочки, но они должны быть защищены от преждевременного создания имени файла оболочкой. Вы можете объединить несколько таких тестов с помощью логического ИЛИ, используя -o
, но вы должны быть осторожны с приоритетом операторов.
Если ваша оболочка поддерживает массивы, вы можете сделать это следующим образом: (Здесь я использую bash
, но аналогичные процедуры должны быть возможны и в других оболочках):
files=( -false )
while IFS= read -r f || [ -n "$f" ]; do files+=( -o -name "*$f"); done < searchFiles.txt
Это должно привести к ${files[@]}
расширению до чередования
-false -o -name *file.a.txt -o -name *file.b.txt -o -name *file.c.txt -o -name *file.d.txt -o -name *file.e.txt
, который вы затем можете использовать в своей команде find
, например
find. \( "${files[@]}" \) -exec grep -Ho '[^ ]*_XYZ' {} +
(Я опустил фиктивный файл /dev/null
в пользу добавления опции -H
). Если количество файлов в searchFiles.txt
слишком велико, этот подход может дать сбой из-за ограничений ARG_MAX
. Вы можете обойти это ограничение, разбив searchFiles.txt
на несколько файлов меньшего размера.
Вы должны быть в состоянии все это с GNU awk
, например:
find. -type f -print0 |
gawk '
step == 1 {files[$0]; next} # record file names in "files" array
step == 2 {
# determine which files to look into (added to ARGV array for
# processing in step 3)
if ($NF in files) ARGV[ARGC++] = $0; next
}
NF {
# record all matches (here in fields matched by FPAT)
$1 = $1 # force a rebuild of $0 joining fields with OFS
matches[FILENAME] = matches[FILENAME] \
(matches[FILENAME] == "" ? "" : OFS) \
$0
}
END {
for (file in matches)
print file ": " matches[file]
}' step=1 searchFiles.txt \
step=2 RS='\0' FS=/ - \
step=3 RS='\n' FPAT='[^ ]*_XYZ' OFS=';'
Выше имена файлов точно соответствуют именам файлов, хранящихся в searchFiles.txt
. Если строки этого файла предназначены для списка суффиксов, вы можете построить регулярное выражение вместо ассоциативного массива:
find. -type f -print0 |
gawk '
step == 1 {
gsub(/[][^$*()+{}?\\.|]/, "\\\\&") # escape regexp operators
regex = regex sep $0; sep = "|"
next
}
step == 2 {
# determine which files to look into (added to ARGV array for
# processing in step 3)
if ($NF ~ ("(" regex ")$")) ARGV[ARGC++] = $0; next
}
NF {
# record all matches (here in fields matched by FPAT)
$1 = $1 # force a rebuild of $0 joining fields with OFS
matches[FILENAME] = matches[FILENAME] \
(matches[FILENAME] == "" ? "" : OFS) \
$0
}
END {
for (file in matches)
print file ": " matches[file]
}' step=1 searchFiles.txt \
step=2 RS='\0' FS=/ - \
step=3 RS='\n' FPAT='[^ ]*_XYZ' OFS=';'
Если вам нужно запутать его, вы можете поместить его в одну строку:
find. -type f -print0|gawk '!s{gsub(/[][^$*()+{}?\\.|]/,"\\\\&");r=r p $0;p="|";next};s==2{if($NF~("("r")$"))ARGV[ARGC++]=$0;next};NF{$1=$1;m[FILENAME]=m[FILENAME](m[FILENAME]==""?"":OFS)$0};END{for(f in m)print f":"m[f]}' searchFiles.txt s=2 RS=\\0 FS=/ - s=3 RS=\\n FPAT='[^ ]*_XYZ' OFS=\;
Они не делают предположений о том, какие символы могут содержать имена и содержимое файлов, за исключением того, что они должны быть допустимыми символами в локали. Суффиксы не могут иметь символ новой строки, но это ограничение определяется форматом вашего searchFiles.txt
.
Вы можете отфильтровать имена файлов в вашем каталоге с помощью grep -f
через текстовый файл с именами, чтобы включить (разрешая частичное совпадение ). Затем сделайте массивный grep
в эти файлы для шаблона поиска и, наконец, отформатируйте результат с помощью небольшого awk
.
Использование GNUbash
:
grep -Ff filenames.txt <(printf '%s\n' *) |
xargs -d '\n' grep -oH '[^[:space:]]*_XYZ$' | awk -F: '
{f[$1] = f[$1] ? f[$1] ";" $2 : $0}
END {for (x in f) print f[x]}'
Некоторые предположения (не все ясны в вопросе):
grep
вывода ). Пробелы обрабатываются. grep
выдаст сообщение, но вернет результаты. grep
ищет шаблон в конце строки. Вы можете изменить его, если хотите, чтобы конец слов совпадал. -H
для grep
используется для углового случая одного файла, для печати имен файлов в выводе (это значение по умолчанию, когда есть два или более файлов)