elenca i file numerati in un intervallo specifico


16

Ho un set di file in una directory numerata come segue:

file1.txt
file2.txt
...
file30.txt
...

Ora, vorrei eseguire un comando su un intervallo specifico di file, diciamo da 18 a 31.

Finora ho usato i seguenti modi,

tre argomenti

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Ora supponiamo che io voglia ogni altro numero,

ciclo continuo

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

sembra che sia un ciclo più affidabile (gli spazi funzionano)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

ma sembra che ci dovrebbe essere un modo più semplice per farlo. Immagino che la soluzione migliore sia quella di creare una funzione bash che restituisca il set di file alla riga di comando. Quindi potrei fare qualcosa come

command `filerange file 18 31`

Ci sono modi o suggerimenti migliori per farlo in modo efficiente?

Mi scuso in anticipo se ho perso questa stessa domanda con risposta da qualche altra parte sul web o su superuser.


Ho aggiornato la mia domanda per includere una soluzione usando un forciclo che consenta spazi nei nomi dei file usando xargs. Sembra funzionare se non hai bash 4. Se hai bash 4, usa sicuramente l'espansione del controvento! Vedi la risposta selezionata. Spina spudorata per aggiornare Snow Leopard bash
milkypostman

Risposte:


25

Prova questo:

for file in file{18..31}.txt

È noto come "espressione di sequenza" e fa parte della funzione di espansione del controvento di Bash . Funziona in Bash 3 e 4.

La funzione di incremento è una novità di Bash 4. Probabilmente hai Bash 3.x.

In Bash 4, puoi fare:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Ma in Bash 3, devi farlo per ottenere gli stessi risultati:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

Lo stesso modulo incrementa di uno:

$ for ((i=1; i<=6; i++)); do echo $i; done

Qualsiasi numero può essere variabile o espressione. Tuttavia, in un'espressione sequenza i numeri devono essere costanti

Ecco un esempio usando quel modulo sui tuoi file:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Un'altra nuova caratteristica delle espressioni di sequenza in Bash 4 è la possibilità di includere zeri iniziali. Ciò è utile se si desidera creare (e utilizzare) file numerati che possono essere ordinati correttamente.

In Bash 4:

touch file{001..010}.txt

creerebbe i file denominati "file001.txt" tramite "file010.txt". I loro nomi verranno ordinati nell'ordine previsto. Senza gli zeri iniziali, "file10.txt" si ordina prima di "file1.txt".

Per lavorare con i file, è possibile utilizzare la stessa sintassi zero iniziale:

for file in file{001..010}.txt; do echo "$file"; done

In Bash 3, se hai bisogno di zeri iniziali, devi aggiungere tu stesso il valore:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

Il printf istruzione anteporrà il valore di i con zeri iniziali, quindi la larghezza è 3, ad esempio ("4" diventa "004").

Modificare:

Accomodare gli spazi nei nomi dei file è semplice:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt

Grazie! Non so dove sia stata tutta la mia vita. L'unica cosa che non riesco a far funzionare è che l'incremento non sembra funzionare nella versione OSX di bash. cioè, non riesco {1..10..2}a lavorare nella mia bash OSX.
milkypostman,

Bene, è perché Snow Leopard (per qualche motivo) usa bash 3.1. Questo è un problema di software.
milkypostman,

@milkypostman: la funzione di incremento e gli zeri iniziali {01..10}sono nuovi in ​​Bash 4. Probabilmente hai Bash 3.x. Se è necessaria la funzione di incremento o per utilizzare le variabili per i limiti dell'intervallo, utilizzare questo modulo: for ((i=1; i<=10; i+=2}(o i++per incrementare di uno). Qualsiasi numero può essere variabile o espressione. Quindi, per utilizzare il valore all'interno del forciclo: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i` che anteporrà il valore icon zeri iniziali, quindi la larghezza è 3, ad esempio ("4" diventa "004").
In pausa fino a nuovo avviso.

Dennis, c'è un modo per aggiornare la tua soluzione per includere il modulo alternativo? Essere un commento è un po 'offuscato quello che probabilmente dovrei ottenere.
milkypostman,

@milkypostman: vedi la mia risposta modificata.
In pausa fino a nuovo avviso.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.