Meu requisito é listar todos os arquivos em um diretório, exceto os que terminam com a ~
(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~
Quero obter apenas esses arquivos:
asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt
~
. Esses arquivos são arquivos de backup criados em alguns editores de texto.ls -l
(letter ell) incluiria permissões, nlinks, proprietário, tamanho e tempo de modificação para cada arquivo listado. O que produziria a saída que você mostra éls -1
(dígito um) e em muitos sistemas-1
é necessário para produzir uma saída em coluna única no terminal , mas quandols
é canalizado (como aqui paragrep
) ou redirecionado,-1
não é necessário, já é uma coluna .Respostas:
A razão pela qual isso não funciona é que o til é expandido para o diretório inicial e, portanto,
grep
nunca vê um til literal. (Veja, por exemplo, o manual do Bash sobre a expansão de Tilde .) Você precisa citá-lo para impedir a expansão, ou seja,Obviamente, 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 local da
ls
saída (embora provavelmente não seja provável que apareça em nomes de usuário, datas ou outras). Se você realmente deseja apenas ignorar arquivos que terminam com um til, você pode usarfonte
A implementação GNU de
ls
(encontrada na maioria dos sistemas Linux) tem uma opção para isso:-B
Ignorar backups:fonte
Se você estiver usando o bash, verifique se
extglob
está ativado:Então você pode usar:
-d
para não mostrar o conteúdo dos diretórios!(*~)
todos os arquivos, exceto os que terminam com~
No zsh, você pode fazer o mesmo com a
kshglob
opção ou usando seus próprios globos estendidos:Como o sufixo a ser excluído tem apenas um caractere, você também pode corresponder aos nomes de arquivos em que o último caractere não é o til (isso também deve funcionar sem
extglob
):Mas a ideia geral é usar
ls --ignore-backups
.fonte
Isso deve ajudar:
Razão: O ~ char é substituído pelo seu diretório inicial antes que o comando seja executado. Experimentar
e
fonte
Como mencionado em outras respostas, é provável que você tenha problemas porque não citou ou 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 o uso desde 2003, o que significa que ele trabalhou em uma variedade muito ampla de implementações de shell em diferentes tipos de sistemas. (aqui eu também uso
-C
porque quero uma boa exibição em colunas classificadas)(uma limitação ao usar a expansão de nome de arquivo shell é que um diretório com um número muito grande de arquivos (sem backup) fará com que a expansão exceda o tamanho da lista de argumentos disponível, embora na maioria dos sistemas modernos esse limite seja bastante alto, geralmente 250 KB ou mais, às vezes muito mais)
fonte
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, ou seja, exclusão) para excluir todas as linhas com o til (~
) no final ($
).No entanto, se você tiver QUALQUER arquivo nomeado como algo1, algo2, é um enorme indicador fedorento de que você tem um fluxo de trabalho ruim, que deve ser corrigido na fonte, não com hacks 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, o que realmente deseja é um sistema de controle de versão
git
.Isso é especialmente verdade no seu caso, onde você tem várias versões de vários arquivos, e o controle de versão parece precisar ser coordenado entre todos os arquivos.
Os sistemas de controle de versão permitem que você sobreponha essencialmente uma janela de tempo no sistema de arquivos, para que você veja apenas um
test
arquivo, 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 configurá-lo, você não precisa mais dos arquivos de backup do seu editor, porque o controle de versão possui 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é "ramificar" a linha do tempo do histórico, experimentando uma nova idéia e voltar no tempo e, em seguida, avançar para tentar uma idéia diferente, se necessário.
fonte
Embora muitas respostas estejam corretas (eu gosto especialmente das respostas
@Foon
), eu observaria que obter a lista de nomesls -l
é um pouco ruim por vários motivos.A ferramenta adequada para encontrar arquivos é, sem surpresa
find
,.Uma de suas conclusões é que é capaz de lidar com a "lógica de seleção" sozinha, por exemplo:
que literalmente diz
find
:.
-maxdepth 1
Lá, procure entidades que
-type f
-a
~
:! -name *~
(onde!
nega a seguinte diretiva que corresponde aos nomes dos arquivos-name *~
).(Para fazer com que toda a correspondência entre tipo e nome apareça como uma unidade lógica, ela deve estar entre parênteses com
(
e)
).-print
.Você precisa proteger alguns caracteres especiais para o shell de serem interpretados pelo shell, e é por isso que os parênteses e o estrondo
!
são escapados por barra invertida e o padrão de nome*~
é cercado por aspas simples.O
find
comando possui uma minilíngua muito poderosa através do uso de suas opções. Por exemplo, pode ser dito para processar recursivamente toda uma árvore (ou árvores) do sistema de arquivos, mas omitir certos diretórios durante a verificação. É possível corresponder a vários atributos dos arquivos - como tempo de criação ou modificação ou tamanho de qualquer que seja.fonte