Рассмотрим этот каталог:

thingsToThinkAbout/
    thing1.txt
    thing2.txt
    thing2.txt.thoughts.txt
    thing3.txt
    thing7.txt.thoughts.txt

С помощью bash find я могу искать вещи (find . -name "thing*.txt"), мысли (find . -name "thing*.txt.thoughts.txt") или оба (find . -name "*.txt"), но могу ли я использовать команду для поиска также по родным братьям ?

В моем примере я не думал о thing1.txt и thing3.txt , и у меня есть некоторые мысли о "вещи 7", которой не существует. Чтобы найти их, мне нужно найти файлы X, у которых нет братьев и сестер по имени Y. Как это можно сделать?

Очевидно, я мог бы написать полный скрипт с if s, но нужно ли это?

1 ответ1

1

Заметка

С помощью bash find я могу искать вещи (find . -name "thing*.txt")

Вы пробовали это? Это тоже найдет мысли. Следующий вызов find исключает их:

find . -name "thing*.txt" ! -name "*.thoughts.txt"

Ответ

Чтобы найти вещи без мыслей, вы можете использовать -exec (или -execdir) в качестве теста. Это успешно, если вызванная команда возвращает состояние выхода 0 . В этом случае команда является test:

find . -name "thing*.txt" ! -name "*.thoughts.txt" -exec test ! -e "{}.thoughts.txt" \; -print

Как видите, добавить к имени строку довольно просто ("{}.thoughts.txt"). Чтобы найти мысли без вещей, вы в основном делаете то же самое, но вам нужно удалить некоторую строку; это не так просто. Дополнительная оболочка может сделать это:

find . -name "thing*.txt.thoughts.txt" -exec sh -c 'test ! -e "${1%.thoughts.txt}"' sh {} \; -print

${1%.thoughts.txt} возвращает $1 с .thoughts.txt с самого конца. Мы проверяем, если этот файл не существует.

Замечание find … -exec test … выполняет исполняемый файл test , в то время как sh -c 'test …' использует встроенный test sh . Это не одно и то же, в этом случае это не должно иметь значения.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .