Подсчет количества файлов в каталоге, которые содержат различные переменные в моем массиве - bash скрипт - PullRequest
0 голосов
/ 17 января 2020

У меня есть сценарий bash, который должен проверять определенные файлы на наличие определенных переменных и подсчитывать, сколько файлов возвращается с этими переменными.

Так как мне нужно искать более одной переменной Я решил использовать массив для переменных.

Код, который я использую ниже:

#!/bin/bash

declare -a MYARRAY=('Variable One' 'Variable Two' 'Variable Three');
COUNT_MYARRAY=$(find $DIRECTORY -mtime -1 -exec grep -ln $MYARRAY {} \; | wc -l)

Я объявил $ DIRECTORY в моем реальном скрипте. Тем не менее, кажется, что он не подхватывает файлы, если в них есть вторая и третья переменная?

Может кто-нибудь увидеть, где я могу ошибаться?

Ответы [ 2 ]

1 голос
/ 17 января 2020

Неправильно:
С echo $MYARRAY вы найдете Variable One, а не строку, которую вы хотите для grep.
Также обратите внимание, что для имен переменных лучше использовать строчные буквы. Я буду использовать ${directory}, а не $DIRECTORY (и в двойных кавычках для каталогов с пробелом).

У вас есть больше вариантов с grep. Если вы хотите, чтобы файл с 8 экземплярами считался один, вы не можете использовать опцию grep -c. Полезная опция -r. Вы ищете что-то вроде

grep -Erl "Variable One|Variable Two|Variable Three" | wc -l

Это сложно, когда переменные могут иметь специальные символы, такие как $ или |.
Другой вариант grep использует параметр -f FILE, Obtain patterns from FILE, one per line

Таким образом, вы должны создать функцию, которая записывает переменные в файл, и использовать что-то вроде

grep -rlFf "myVariablesFile" "${directory}" | wc -l

Когда содержимое файла быстро меняется, вы можете избежать временного файл с

grep -rlFf <(function_that_writes_variables_to_stdout) "${directory}"| wc -l

или напрямую

grep -rlFf <(printf "%s\n" "${var1}" "${var2}" "${var3}") "${directory}" | wc -l
1 голос
/ 17 января 2020

Вы можете использовать регулярное выражение grep s и передавать несколько выражений, используя 'var1\|var2'. Сначала создайте аргумент grep, а затем выполните grep.

Вам не нужны номера строк от -n до grep для подсчета файлов ...

grep может обрабатывать несколько файлов - быстрее будет передать несколько файлов одному grep с -exec ... +, а не spawn grep для каждого файла.

UPPER_CASE_VARIABLES кричат ​​на меня, и по соглашению переменные верхней вазы зарезервированы для экспортируемых переменные.

myarray=('Variable One' 'Variable Two' 'Variable Three')
arg=$(printf "%s\|" "${MYARRAY[@]}" | sed 's/\\|$//')
directory=.
count_myarray=$(find "$directory" -type f -mtime -1 -exec grep -l "$arg" {} + | wc -l)

В качестве альтернативы: вы можете передать несколько -exec аргументов для поиска. Итак, сначала из myarray строим аргументы в find в форме -exec grep -l <the var>. Обратите внимание, что несколько переменных могут находиться в одних и тех же файлах, поэтому после grepping получите уникальные имена файлов.

myarray=('Variable One' 'Variable Two' 'Variable Three');
findargs=()
for i in "${MYARRAY[@]}"; do
    findargs+=(-exec grep -l "$i" {} +)
done
directory=.
count_myarray=$(find "$directory" -type f -mtime -1 "${findargs[@]}" | sort -u | wc -l)

или аналогичные:

count_myarray=$(printf '-exec\0grep\0-l\0%s\0{}\0+\0' "${myarray[@]}" | xargs -0 find "$directory" -type f -mtime -1 | sort -u | wc -l)

Не забудьте заключить в кавычки расширения переменных для защиты от пробелов или специальных символы в именах файлов и каталогов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...