Не видя фактического результата, трудно точно сказать, что происходит, но я предполагаю, что это вызвано тем фактом, что команда lsof -p PID
просто распечатывает файлы, которые открываются по указанному PID, а команда lsof | grep PID
распечатывает любые строки, где «PID» находится в любом месте строки. Например, если вы ищете PID = 123, тогда ваша опция grep
также будет печатать строки для PID 1231, 1232, 1233 и т. Д., А также любые файлы, которые находятся в папках с 123 в любом месте их полный путь.
РЕДАКТИРОВАТЬ:
В вашем конкретном примере разница в том, что lsof
игнорирует файлы, открытые потоком. Если вы посмотрите на вывод в примере grep
, третий столбец - это «TID» или идентификатор потока. Строки без TID соответствуют тому, что вы видели, когда использовали параметр -p
. Строки с TID (т. Е. Строки, открытые другими потоками) являются дополнительными.
Если ваш find
поддерживает -execdir
и-printf
:
find. -name a.txt -execdir [ ! -e b.txt ] \; -printf %h\\n
будет искать файлы с именем a.txt
, проверять, есть ли у них родственный файл b.txt
, и если нет, выводить имя содержащего каталога.
Без -execdir
или-printf
:
find. -name a.txt -exec sh -c '
for file do
dir=${file%/*}
[ -e "$dir/b.txt" ] || printf "%s\n" "$dir"
done' sh {} +
Он также более эффективен, так как не выполняет одну команду для каждого файла.
Сzsh
:
printf '%s\n' **/*(D/e'{[[ -e $REPLY/a.txt && ! -e $REPLY/b.txt ]]}')
Или:
printf '%s\n' **/a.txt(D^e'{[[ -e $REPLY:h/b.txt ]]}':h)