Find files based on siblings

0

Consider this directory:

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

With bash find I can look for the things (find . -name "thing*.txt"), the thoughts (find . -name "thing*.txt.thoughts.txt") or both (find . -name "*.txt"), but can I use the command to search based on siblings as well?

In my example, I did not think about thing1.txt and thing3.txt, and I have some thoughts about a "thing 7", which doesn't exist. To find those, I would have to look for files X who do not have siblings named Y. How could this be done?

Obviously, I could write a complete script with ifs, but is that needed?

Bowi

Posted 2018-07-10T14:59:44.610

Reputation: 995

Answers

1

Note

With bash find I can look for the things (find . -name "thing*.txt")

Have you tried this? This will find thoughts as well. The following find invocation excludes them:

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

Answer

To find things without thoughts you can use -exec (or -execdir) as a test. It succeeds if the invoked command returns exit status of 0. In this case the command is test:

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

As you can see it's quite easy to add a string to the name ("{}.thoughts.txt"). To find thoughts without things you basically do the same, but you need to remove some string; it's not so easy. An extra shell can do this:

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

${1%.thoughts.txt} returns $1 with .thoughts.txt removed from the very end. We check if this file doesn't exist.

Note find … -exec test … executes the test executable, while sh -c 'test …' uses the test builtin of sh. These are not the same, it shouldn't matter in this case though.

Kamil Maciorowski

Posted 2018-07-10T14:59:44.610

Reputation: 38 429