Як зібрати тисячі файлів у каталозі на сотні рядків у файлі


11

Я намагаюся скласти grepзаяву, і це мене вбиває. Я також втомився отримувати arguments list too longпомилку. У мене є файл, давайте назвемо його subset.txt. Він містить сотні рядків із конкретними рядками, такими як MO43312948. У моєму об'єктовому каталозі є тисячі файлів, і мені потрібно скопіювати всі файли, що містять рядки, перелічені в subset.txtінший каталог.

Я намагався почати з цього, щоб просто повернути відповідні файли з каталогу об’єктів.

grep -F "$(subset.txt)" /objects/*

Я продовжую отримувати `bash: / bin / grep: Список аргументів занадто довгий``


6
Чому ви ввели "$(subset.txt)"таку команду? Тобто команда заміна , яка зробить вашу оболонку виконати subset.txt (як якщо б це була команда або скрипт).
JigglyNaga

Відповіді:


23

Ви можете передати каталог в якості мішені для grepз -Rі файл вхідних патернів з -f:

  -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  If this option is used
          multiple  times  or  is  combined with the -e (--regexp) option,
          search for all patterns given.  The  empty  file  contains  zero
          patterns, and therefore matches nothing.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

Отже, ви шукаєте:

grep -Ff subset.txt -r objects/

Список відповідних файлів можна отримати за допомогою:

grep -Flf subset.txt -r objects/

Отже, якщо ваш остаточний список не надто довгий, ви можете просто зробити:

 mv $(grep -Flf subset.txt -r objects/) new_dir/

Якщо це повертає argument list too longпомилку, використовуйте:

grep -Flf subset.txt -r objects/ | xargs -I{} mv {} bar/

І якщо назви ваших файлів можуть містити пробіли або інші дивні символи, використовуйте (припускаючи GNU grep):

grep -FZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

Нарешті, якщо ви хочете виключити бінарні файли, використовуйте:

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

… Або уникати потенційно тисяч mvвикликів з одним аргументом кожен: ... | xargs -0 mv -t bar/(якщо ви mvпідтримуєте цей -tваріант).
Девід Фоерстер

11

використання

grep -F -f subset.txt 

сказати grep читати з subset.txtфайлу.

ви можете використовувати файл find для переходу до файлу.

find . -type f -exec grep -F -f subset.txt {} \;

або

find . -type f -exec grep -F -f subset.txt {}  +

Будь-яка перевага використання findзамість того, -rщо ви робите додаткову фільтрацію?
phk

1
@phk здійснює grep -rпошук у символьних посиланнях на звичайні файли, що може бути або не бажано (якщо вони вказують всередині одного дерева, ви шукаєте один і той же файл двічі; якщо вони вказують назовні, ви шукаєте файл, який може бути, а може і не бажати).
Жил "ТАК - перестань бути злим"

У сучасних версіях grepє параметри управління їх взаємодією із символічними посиланнями ( man grepдля визначення специфіки для поточної системи). Рекурсивна робота grepбуде набагато швидшою, ніж запуск grepокремо на кожному файлі через find.
Перрі

1
@Perry, ви впевнені в цьому? Чому? Також зауважте, що ця відповідь використовується -exec +, тому вона буде групувати файли, а не запускати по одному грепу на файл.
тердон

Я виправданий, я не знав про різну семантику -exec {} +проти -exec {} \;… Ви щодня дізнаєтесь щось нове (я все ще не бачу жодної причини, чому один рекурсивний grepзвичай не буде швидшим, ніж grepзапуск з декількох с, findзавдяки створенню процесу та аналізу синтаксису, але я не мають конкретних номерів, щоб підкріпити це).
Перрі

3

Якщо ви хочете ще більше прискорити grep, перед тим, як запустити його, ви можете встановити локаль у своїй оболонці, тобто використати "LC_ALL = c". Це буде успадковано в grep і відключить обробку Unicode, коли це не потрібно, а в деяких випадках може різко прискорити grep. Чудовий блог із документами про це можна знайти на веб- сайті http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all . Цей трюк також може пришвидшити скрипти скриптів для оболонки, а не лише grep.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.