Listar arquivos que não possuem outro arquivo com sufixo

3

Considere um diretório com os seguintes arquivos:

file1
file1.suffix
file2
file3
file3.suffix

Eu preciso listar todos os arquivos de forma que não exista outro arquivo com o mesmo nome e um sufixo conhecido. No exemplo acima, isso corresponderia apenas a file2 .

Isso é o que eu criei:

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

Existe uma maneira mais simples e mais curta?

Editar 1

No meu caso concreto, existem vários sufixos (arquivos de zona de ligação / w dnssec):

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

Estou tentando listar zonas que não tenham o dnssec ativado, ou seja, arquivos que não tenham outro arquivo com a extensão .signed .

Esta é minha tentativa:

diff --new-line-format= --unchanged-line-format= \
    <(ls -I '*.jbk' -I '*.jnl' -I '*.signed' -I '*.signed.jnl' | sort) \
    <(ls *.signed | sed 's/\(.*\)\.signed//' | sort)
    
por Joe 11.12.2017 / 13:56

3 respostas

4

com zsh :

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

(ou use ^*.* em vez de ^*.suffix se você quiser considerar apenas os arquivos sem extensão ou, seguindo a atualização da sua pergunta *.(org|net|com) ou ^*.*.* ou ^*.(signed|jnl|jbk) ...)

Isso é listar os arquivos que não são .suffix , para os quais file.suffix não existe usando o qualificador e glob para selecionar arquivos com base na e valuation de algum código (em que $REPLY contém o valor caminho do arquivo para selecionar).

Outra abordagem usando o operador de disjunção de matriz ${a:|b} (mnemônico: elementos de a barra aqueles de b ):

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

ls -ld -- é usado apenas como um exemplo de comando aqui, você pode usar qualquer outro comando ou armazenar a lista em uma matriz como:

without_suffix=(${bare:|with_suffix})
    
por 11.12.2017 / 14:25
3

Como sua lista de arquivos atuais tem uma convenção de nomenclatura simples - aqui está a abreviação ls + cut + uniq approach:

ls -v1 * | cut -d'.' -f1 | uniq -u
    
por 11.12.2017 / 14:13
1

Não sei se é mais curto, mas sim diretamente no shell (Bash e zsh rapidamente testados):

for f in * ; do 
    [[ $f != *.suffix ]] && ! [[ -f "$f.suffix" ]] && echo "$f"
done

(ou substitua echo por algo sensato)

Ou o mesmo com vários sufixos:

suffixes=(suffix postfix)
for f in * ; do 
    for s in "${suffixes[@]}" ; do 
        [[ $f == *".$s" ]] || [[ -f "$f.$s" ]] && continue 2
    done
    echo "$f"
done
    
por 11.12.2017 / 14:14

Tags