Чтобы сделать это именно так, как вы хотите:
find -L /home/blast/dirtest/ -maxdepth 3 \
-printf '%p@%y/#/%TY-%Tm-%Td %TX/#/%s/#/%f/#/%l/#/%h\n' \
> tmp.out
cut -d@ -f1 tmp.out \
| xargs grep -l "pattern" 2>/dev/null \
| sed 's/^/^/; s/$/@/' \
| grep -f /dev/stdin tmp.out \
| sed 's/^.*@//'
Это работает при условии, что у вас нет символов @
в именах файлов.
То, что он делает, это избежать Сначала выполните grep и просто выведите все файлы с запрошенными метаданными во временный файл.
Но в каждой строке также указывается полный путь (%p@
).
Затем мы извлекаем ( cut
) полные пути из этого списка и список файлов, которые содержат шаблон (xargs grep
).
Затем мы используем sed
, чтобы префиксить каждое такое имя файла с ^
и добавить к нему суффикс с @
, что делает его шаблоном в нашем файле tmp.out
.
Затем мы используем этот шаблон (grep -f /dev/stdin
), чтобы извлечь только те пути из большого списка в tmp.out
.
Теперь все, что осталось, это удалить искусственный полный путь, к которому мы добавили префикс, с помощью последней команды sed
.
Видя, как вы использовали /home
, есть большая вероятность, что вы используете Linux , который, если вы готовы принять некоторые изменения формата вывода, позволяет вам o это несколько элегантнее:
find -L /home/blast/dirtest/ -maxdepth 3 \
| xargs grep -l "pattern" 2>/dev/null \
| xargs stat --printf '%F/#/%y/#/%s/#/%n\n'
Вывод stat --printf
отличается от find -printf
(и от MacOS 'stat -f
), но это та же информация.
Заметьте, однако, что, поскольку вы передали -L
для поиска, и вы получаете результат:
- Результаты ограничены типами файлов, которые можно подбирать, поэтому они будут никогда не быть каталогами, ссылками и т. д. c ..
- Если вы наткнетесь на неработающую ссылку, она не будет в выводе, потому что она не может быть найдена.