Поиск текста в файлах того же имени в нескольких папках различных глубин

Ситуация: В Linux у меня есть родительская папка почти с 100 папками различных имен. Каждая папка имеет файл ResourceParent.xml и сотни различных номеров версий, каждые из которых имеют свое собственное ResourceVer.xml файл. Я интересуюсь обоими ResourceParent.xml в 1-й папке уровня и ResourceVer.xml в папке Последней версии (самое большое количество), например. ver548.

Я должен искать в каждом файле 3 тега .txt|.csv|.xls и возвратите информацию в этих тегах в файл report.txt. Теги обычно на той же строке, таким образом, я думаю Grep, в порядке.

Что я попробовал:

grep -nr -E ".txt|.csv|.xls" . > /dir/to/the/ReportFile.txt

Это берет слишком долго, поскольку это ищет в каждых из тысяч каталогов и производит много ненужных дублированных данных.

Кроме того, я попытался войти в каждую папку в зависимости от того, что я ищу и запускаю этот скрипт, который является уменьшенными дубликатами немного лучшего ре и более соответствующими данными, но это является все еще слишком громоздким.

Вопрос: Как делают я запускаю скрипт Linux для поиска тегов в файловой структуре, которая похожа на это: Теги интереса внутри .xml файлы:

".txt|.csv|.xls"

текущее местоположение:

/dir

Файл интереса 1:

/dir/par/ResourceParent.xml

Файл интереса 2:

(нужно последнее ver число),

/dir/par/ver###/ResourceVer.xml

Необходимый выходной файл:

ResourceReport.txt

Обновление

Я нашел ls | tail -1 выбирает папку с самым большим ver числом. Таким образом, я думаю, что ответ включает это..

2
задан 15 January 2019 в 16:45

1 ответ

Возможно, с двумя командами...

grep --include="ResourceParent.xml" -r -E '.txt|.csv|.xls' > file
for d in par*; a=("$d"/*); b=($(sort -V <<<"${a[*]}")); grep -HE '.txt|.csv|.xls' "${b[@]: -1}"/*; done >> file

Второй помещает содержание каждого каталога в par уровень в массив, отсортированный по номеру версии так, чтобы можно было искать просто последний объект в массиве. Это, кажется, работает (я получаю последний номер версии), и только занимает несколько секунд на моей тестовой структуре каталогов (первая команда сопровождает вдвое более длинный).

Если Ваши номера версий дополнены так, чтобы они отсортировали естественно для второй команды, Вы смогли бы использовать просто:

for d in par*; a=("$d"/*); grep -HE '.txt|.csv|.xls' "${a[@]: -1}"/*; done >> file

Я имею в виду, ли Ваши числа ver1 ver2 ... ver100, необходимо будет отсортировать массив, но если они ver001, ver002 ... ver100, Вы не должны будете сортировать массив, потому что это будет в правильном порядке так или иначе.

Вы, возможно, должны заменить "${b[@]: -1}"/* с "${b[@]: -1}"/ResourceVer.xml. Я не создал другие файлы. Необходимо будет, по-видимому, также заменить par* с чем-то (я думаю, что Вы сказали, у Вас есть приблизительно 100 каталогов на этом уровне).

Но возможно Вы хотели данные, отсортированные по каталогам на уровне par так, чтобы Вы добрались

data from par1/ResourceParent.xml
data from par1/ver{latest}/ResourceVer.xml
data from par2/ResourceParent/xml
data from par2/ver{latest}/ResourceVer.xml

Вы могли выполнить некоторую обработку текста на выходном файле, но это зависит как Ваш par каталоги называют. Так как я назвал их par1 par2 ... par200

sort -V file >> betterfile

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

Вы могли также урезать имена файлов при помощи grep -h (вместо -H) в исходных командах (хотя это означало бы, что Вы не могли отсортировать данные впоследствии по вышеупомянутому методу), или по обработке текста в конце, например, если бы Ваши имена файлов не имеют никаких двоеточий или новых строк, это было бы довольно надежно:

sed 's/^[^:]*://' file

Можно записать в файл вместо stdout путем добавления -i флаг к sed после тестирования.


Благодаря John1024, ответ которого на U&L обеспечивает отличный способ получить последнее имя файла, которое не полагается на парсинг вывода ls или find или бесплатно цикл по структуре для подсчета повторений.

3
ответ дан 2 December 2019 в 02:41

Другие вопросы по тегам:

Похожие вопросы: