Listar intervalo de arquivos com curingas UNIX

14

Digamos, por exemplo, eu tenho os seguintes arquivos no meu diretório de trabalho: mjk0001.fits, mjk0002.fits, ... aumentando numericamente todo o caminho para mjk9999.fits.

Existe uma maneira de usar curingas UNIX para listar ou operar em um grupo seqüencial deles? Por exemplo, se eu precisar executar um processo de 0025 a 0050, que formato eu usaria?

Eu tentei o seguinte, mas não tive sucesso:

ls *[25-50].fits
ls mjk00[25-50].fits
ls mjk[0025-0050]*
ls *[0025-0050]*

Agradecemos antecipadamente a todos, MK

Matt Keene
fonte
Para referência: correspondência padrão , englobamento
Ignis

Respostas:

20

Você pode usar a expansão de chaves:

ls mjk00{25..50}.fits

Zeros à esquerda podem ser incluídos, se necessário:

ls mjk0{000..149}.fits
chepner
fonte
1
Usando essa sintaxe, você também pode especificar um valor etapa: {25..50..2}.
Nobar
1

Não diretamente, mas você pode usar vários padrões glob:

ls mjk002[56789].fits mjk00[34]?.fits

Não é exatamente o que você está procurando, mas é a coisa mais próxima que os padrões glob oferecem, e certamente é melhor do que digitar cada sistema de arquivos. Pelo menos o número de padrões necessários por intervalo numérico é limitado pelo log dos pontos de extremidade numéricos do intervalo.

Celada
fonte
1

Você pode usar um regex com grep. Eu não sou um guru de regex. A seguir, o padrão retorna os números entre 25 e 50:

ls | sort -n | grep -E 'mjk00([2][5-9]|[3-4][0-9]|[5][0]).fits'

Eu não sei se é possível e como, eventualmente, generalizar isso com grep.

Heisenbug
fonte
0

Pode ser possível obter maior portabilidade ou flexibilidade usando um forloop e printf:

for i in $(seq 25 50 1) ; do ls --escape $(printf "mjk%04d*" $i) ||true; done

Isso lida bem com os espaços e os resultados são adequados para tubulações e xargspara processamento adicional.

Números com várias correspondências resultarão na listagem de todos os arquivos correspondentes.

Números sem correspondências reportarão um erro no stderr, mas ||truesuprimem um retorno de erro no nível do bash.


No caso básico, porém, usar fore printfnão é diferente do mais conciso:

ls --escape mjk{0025..0050..1}* ||true
nobar
fonte
Se você deseja separar os resultados da expansão de chaves, use um loop for:for i in {025..050} ; do ... ; done
nobar 7/17/17