Listando com `ls` e expressão regular


15

Como posso listar arquivos com um nome de arquivo que termina com o último caractere e com a .txtextensão?

Eu tentei, ls *+([[:digit:]]).txtmas isso é verdade para abc12.txte abc2.txt.

Mas eu preciso pegar apenas abc2.txt. Como eu posso fazer isso?

Existe alguma forma de :digit:fazer isso?


2
Padrão que deve ser observado é válido somente com estendido englobamento endabled: shopt -s extglob.
precisa saber é o seguinte

Respostas:


20

E se:

ls *[!0-9][0-9].txt

O !início do grupo complementa seu significado.

Conforme observado nos comentários, isso é coisa do bash, tente por exemplo:

printf "%s\n" *[!0-9][0-9].txt

2
Observe que o bash (ou seja ls) não suporta expressões regulares aqui. Estas são expressões de nome de arquivo (Globbing) . Você pode ver a diferença já no seu exemplo: aqui, *é um curinga, que não existe nas expressões regulares, onde você usaria .*para obter o mesmo. Expressões regulares são muito mais poderosas do que globbing.
Christopher K.

2

A pergunta pedia expressões regulares. O Bash e, portanto ls, não suporta expressões regulares aqui. O que ele suporta são expressões de nome de arquivo ( Globbing ), uma forma de curingas. Expressões regulares são muito mais poderosas que isso.

Se você realmente deseja usar expressões regulares, pode usar o find -regexseguinte:

find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt'

A localização é recursiva por padrão, mas lsnão é. Para encontrar apenas arquivos no diretório atual, você pode desativar a recursão com -maxdepth 1. Encontre correspondências no nome do arquivo com path, é por isso que os nomes de arquivos começam com ./se você executar find in .. O regex começa com \./para lidar com isso. Observe que em uma regex, .é um caractere especial que corresponde a qualquer caractere, mas aqui realmente queremos um ponto, é por isso que o escapamos com uma barra invertida. Fazemos o mesmo para o ponto in .txt, porque a regex também corresponderia Atxt. As classes de dígitos são as mesmas que para os globbing, apenas o que você precisa em ^vez de !inverter a classe de caracteres.

Se você deseja obter a saída de ls, então você pode usar -exec lsassim:

 find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt' -exec ls -lah {} \;

findsuporta alguns tipos diferentes de expressões regulares. Você pode especificar um -regextype, por exemplo:

find . -maxdepth 1 -regextype egrep -regex '\./.*[^0-9][0-9]\.txt'

Para mim, os tipos possíveis são: 'findutils-default', 'awk', 'egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic' , 'posix-egrep', 'posix-extended', 'posix-minimal-basic', 'sed' Você pode executar find -regextype helppara descobrir o que é suportado no seu sistema.


0

Com os globos estendidos do ksh (ou bash -O extglobou zsh -o kshglob) que você já está usando, isso seria:

ls -d -- ?(*[![:digit:]])[[:digit:]].txt

Ou

ls -d -- !(*[[:digit:]])[[:digit:]].txt

Se você quiser combinar a1.txt e2.txt não, a12.txtnem nem 12.txt.

No entanto, observe que no ksh e no bash (a menos que você defina a failglobopção de obter um comportamento semelhante ao do zsh), se esse padrão não corresponder a nenhum arquivo, o padrão será passado literalmente para lse se esse arquivo (com nome estranho) acontecer com existir, será listado porls mesmo que não corresponda ao próprio padrão.

Para incluir .2.txt, defina a dotglobopção bash, adicione o (D)qualificador glob em zsh, ou conjunto FIGNOREde !(.|..)no ksh93.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.