Bash - Como encontrar todos os arquivos NÃO no array

1

Eu tenho vários arquivos em um diretório e uma lista de arquivos esperados nele.

Por exemplo: arquivos que eu tenho são:

  • file1
  • arquivo2
  • file3

os arquivos esperados são

  • file1
  • arquivo2
  • file4

Gostaria de testar o diretório e descobrir que o arquivo4 NÃO está nele.

    
por Adam 28.03.2017 / 22:46

4 respostas

2

Supondo que você tenha uma matriz com os nomes de arquivos e queira descobrir quais não estão presentes no diretório, faça um loop pela matriz e verifique se os arquivos existem. ( -f testa arquivos regulares, -e para qualquer tipo)

files=(file1 file2 file4)
for f in "${files[@]}" ; do 
    [ -f "$f" ] || echo "$f: not found"
done 

O oposto é semelhante, mas requer um loop duplo ou transformar o array em um array associativo. Com o laço duplo:

files=(file1 file2 file4)
for f in * ; do
        found=0
        for g in "${files[@]}" ; do
                [ "$f" = "$g" ] && found=1
        done
        [ "$found" = 0 ] && echo "$f: in directory but not listed"
done 
    
por 28.03.2017 / 22:49
4

Para conjunção e disjunção de matriz, veja zsh em vez de bash .

$ expected=(file1 file2 file4)
$ existing=(file1 file2 file3) # or existing=(file*) to use globbing

$ echo missing: ${expected:|existing}
missing: file4
$ echo found: ${expected:*existing}
found: file1 file2
$ echo unexpected: ${existing:|expected}
unexpected: file3

Mnemônico (meu, pelo menos, não sei se são os oficiais):

  • ${A:|B} : elementos de $A bar os de $B
  • ${A:*B} : elementos de $A estrelando os de $B .
por 29.03.2017 / 01:11
0

Se você tiver que testar um monte de arquivos, uma função é uma solução melhor. Caso contrário, um simples ls do arquivo será suficiente! Abaixo está a saída que você obterá quando o arquivo que você está procurando não estiver lá:

../theDirIWantToCheck $ ls theFileIWantToFind.txt
ls: theFileIWantToFind.txt: No such file or directory

Também recomendo utilizar a conclusão de tabulação. Dê o comando ls e comece a digitar o nome de qualquer arquivo que você espera. Você só tem que dar alguns caracteres e, em seguida, pressione tab (se isso não funcionar, pressione a tecla duas vezes). Todos os nomes de arquivo correspondentes a esse padrão serão apresentados se existirem.

$ ls fi<tab>
file1.txt file2.txt file3.txt file_new.txt filetypes.txt

Você também pode transmitir ls vários argumentos para verificar vários arquivos:

$ ls file1.txt file2.txt file3.txt
...

Se os arquivos compartilharem o mesmo prefixo de padrão (como acima: arquivo1, arquivo2, arquivo3), você poderá usar a expansão de chave. Isso é como passar todos os três argumentos em uma forma condensada. O .. representa um intervalo.

$ ls file{1..3}.txt
ls: file1.txt: No such file or directory
ls: file2.txt: No such file or directory
ls: file3.txt: No such file or directory

Como alternativa, você pode usar um curinga para passar todos os padrões de correspondência possíveis com o prefixo comum "file" (como file1.txt, file_other.txt):

$ ls file*
...

Finalmente, você pode passar todos os argumentos em uma matriz para ls e deixar que ela faça a impressão para você, em vez de usar echo . Além disso, se você usar a opção -l para ls , quando os arquivos existirem, você poderá obter alguns detalhes adicionais sobre eles, como permissões, tamanho do arquivo e data / hora da última modificação.

    
por 29.03.2017 / 10:30
0
perl -le '-e or print for qw/file1 file2 file4/'
    
por 29.03.2017 / 13:32