Evite listar os arquivos que terminam com ~ (arquivos de backup)

19

Meu requisito é listar todos os arquivos em um diretório, exceto os arquivos que terminam com ~ (arquivos de backup).

Eu tentei usar o comando:

ls -l | grep -v ~    

Eu recebo esta saída:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

Eu quero apenas obter estes arquivos:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt
    
por curious_one 26.09.2018 / 14:50

7 respostas

48

ls -l | grep -v ~

A razão pela qual isso não funciona é que o til é expandido para o seu diretório pessoal, então grep nunca vê um til literal. (Veja, por exemplo, o Manual do Bash sobre a Expansão do Tilde .) Você precisa citá-lo para impedir a expansão, ou seja,

ls -l | grep -v "~"

Naturalmente, isso ainda removerá qualquer linha de saída com um til em qualquer lugar, mesmo no meio de um nome de arquivo ou em outro lugar na saída ls (embora provavelmente não seja provável que apareça em nomes de usuários, datas ou outros). Se você realmente quer apenas ignorar arquivos que terminam com um til, você pode usar

ls -l | grep -v "~$"
    
por 26.09.2018 / 14:55
47

A implementação GNU de ls (encontrada na maioria dos sistemas Linux) tem uma opção para isso: -B Ignore backups:

ls --ignore-backups
    
por 26.09.2018 / 14:52
24

Se você estiver usando o bash, verifique se extglob está ativado:

shopt -s extglob

Então você pode usar:

ls -d -- !(*~)
  • -d para não mostrar o conteúdo dos diretórios
  • !(*~) de todos os arquivos, exceto os que terminam com ~

No zsh, você pode fazer o mesmo com a opção kshglob ou usando seus próprios globs estendidos:

setopt extended_glob
ls -d -- ^*~

Mas a ideia geral é usar ls --ignore-backups .

    
por 26.09.2018 / 14:55
12

Isso deve ajudar:

ls -l | grep -v '~'  

Razão: O ~ char é substituído pelo seu diretório inicial antes do comando ser executado. Experimente

echo ~

e

echo '~'
    
por 26.09.2018 / 14:54
6

Como mencionado em outras respostas, a razão pela qual você provavelmente está tendo problemas é porque você não citou nem escapou do til.

Para um caso de uso específico, usei a expansão de nome de arquivo do shell para fazer algo semelhante. Eu tenho usado desde 2003, o que significa que tem trabalhado em uma ampla variedade de implementações de shell em diferentes tipos de sistemas. (aqui eu também uso -C porque eu quero uma boa exibição em colunas ordenadas)

ls -C *[!~]

(uma limitação com o uso da expansão de nome de arquivo shell é claro que um diretório com um número muito grande de arquivos (não-backup) fará com que a expansão exceda o tamanho da lista de argumentos disponível, embora na maioria dos sistemas modernos o limite é bastante alto, geralmente 250KB ou mais, às vezes muito mais)

    
por 26.09.2018 / 21:14
1

ls | grep -v '~$' é a solução rápida. Ele usa ls para listar todos os arquivos (não ocultos) e, em seguida, usa grep com -v (correspondência invertida, isto é, exclusão) para excluir todas as linhas com o til ( ~ ) no final ( $ ). / p>

No entanto, se você tiver QUALQUER arquivo com o nome algo1, algo2, é um indicador ruim que você tem um fluxo de trabalho ruim, que deve ser corrigido na fonte, e não com truques desajeitados, como modificar o funcionamento do ls.

Se você estiver nomeando arquivos com números de versão, como test1 e test2 ou testone e testtwo, então o que você realmente quer é um sistema de controle de versão, como git .

Isso é especialmente verdadeiro no seu caso, no qual você tem várias versões de vários arquivos, e a versão parece precisar ser coordenada entre todos os arquivos.

Sistemas de controle de versão permitem que você essencialmente sobreponha uma janela de tempo no sistema de arquivos, para que você veja apenas o arquivo test , mas sob o capô (através do programa de controle de versão) todas as versões estão disponíveis para pesquisar, recuperar, reverter para, comparar com, etc.

Depois de configurar, você não precisará mais dos arquivos de backup do editor, pois o controle de versão tem o histórico dos arquivos desde que você começou a usá-lo, mesmo que você tenha feito mil alterações desde então. Você pode até mesmo "ramificar" a linha do tempo do histórico, experimentando uma nova ideia, e voltando no tempo e depois avançando para tentar uma ideia diferente, se for necessário.

    
por 28.09.2018 / 10:50
1

Embora muitas respostas estejam corretas (eu gosto do @Foon em particular), eu notaria que obter a lista de nomes com ls -l é um pouco ruim por vários motivos.

A ferramenta adequada para encontrar arquivos é, sem surpresa, find .

Um dos seus resultados é que é capaz de lidar com "lógica de seleção" por si só, por exemplo:

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

que literalmente diz find para:

  1. Procure por arquivos no diretório atual: .
  2. Somente procure-os no nível desse diretório, ou seja, não recurse: -maxdepth 1
  3. Lá, procure entidades que

    • do tipo de arquivo: -type f
    • e: -a
    • cujos nomes não terminam em ~ : ! -name *~ (onde o ! nega a seguinte diretiva que corresponde aos nomes dos arquivos, -name *~ ).

    (Para fazer o jogo inteiro no tipo e nome aparecer como uma unidade lógica, é entre parênteses com ( e ) ).

  4. Imprima o nome de cada arquivo encontrado: -print .

Você precisa proteger alguns caracteres especiais para o shell de ser interpretado pelo shell, e é por isso os parênteses e o estrondo, ! , estão com escape de barra invertida, e o padrão de nome, *~ , está entre aspas simples.

O comando find possui um mini-idioma muito poderoso através do uso de suas opções. Por exemplo, pode ser dito para processar recursivamente uma árvore inteira do sistema de arquivos (ou árvores), mas omitir determinados diretórios durante a digitalização. É possível combinar em vários atributos dos arquivos - como criação ou modificação tempo ou tamanho de qualquer coisa.

    
por 30.09.2018 / 18:48

Tags