List files not having another file with suffix

diff()findlszsh

Consider a directory with the following files:

file1
file1.suffix
file2
file3
file3.suffix

I need to list all files such that there doesn't exist another file having the same name and a known suffix. In the example above that would match only file2.

This is what i came up with:

diff --new-line-format= --unchanged-line-format= \
    <(ls -I '*.suffix' | sort) \
    <(ls *.suffix | sed 's/\(.*\)\.suffix/\1/' | sort)

Is there a simpler and shorter way?

Edit 1

In my concrete case there's actually multiple suffixes (bind zone files /w dnssec):

example.org
example.org.jbk
example.org.jnl
example.org.signed
example.org.signed.jnl
example.com

I'm trying to list zones that don't have dnssec enabled, that is, files that don't have another file with .signed extension.

This is my attempt:

diff --new-line-format= --unchanged-line-format= \
    <(ls -I '*.jbk' -I '*.jnl' -I '*.signed' -I '*.signed.jnl' | sort) \
    <(ls *.signed | sed 's/\(.*\)\.signed/\1/' | sort)

Best Answer

With zsh:

setopt extendedglob # for the first "^" below
ls -ld -- ^*.suffix(^e:'[[ -e $REPLY.suffix ]]':)

(or use ^*.* instead of ^*.suffix if you only want to consider the extension-less files, or, following the update to your question *.(org|net|com) or ^*.*.* or ^*.(signed|jnl|jbk)...)

That is list the non-.suffix files, for which file.suffix doesn't exist using the e glob qualifier to select files based on the evaluation of some code (where $REPLY contains the path of the file to select).

Another approach using the ${a:|b} array subtraction operator (mnemonic: elements of a bar those of b):

bare=(^*.suffix(N))
with_suffix=(*.suffix(N:r))
ls -ld -- ${bare:|with_suffix}

ls -ld -- is only used as an example command here, you can use any other command or store the list in an array like:

without_suffix=(${bare:|with_suffix})
Related Question