daftar file bernomor dalam rentang tertentu

16

Saya memiliki satu set file dalam direktori bernomor sebagai berikut:

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

Sekarang, saya ingin menjalankan perintah pada rentang file tertentu, katakanlah 18 hingga 31.

Sejauh ini saya telah menggunakan cara-cara berikut,

tiga argumen

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

Sekarang anggaplah saya ingin setiap nomor lainnya,

lingkaran

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

sepertinya ini adalah loop yang lebih andal (spasi bekerja)

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

tetapi sepertinya harus ada cara yang lebih sederhana untuk melakukan ini. Saya menduga solusi terbaik adalah membuat fungsi bash yang akan mengembalikan set file ke baris perintah. Maka saya bisa melakukan sesuatu seperti,

command `filerange file 18 31`

Adakah cara atau saran yang lebih baik untuk melakukan ini secara efisien?

Saya minta maaf sebelumnya jika saya melewatkan pertanyaan yang sama ini dijawab di tempat lain di web atau di superuser.

milkypostman
sumber
Saya memperbarui pertanyaan saya untuk memasukkan solusi menggunakan forloop yang memungkinkan ruang dalam nama file menggunakan xargs. Tampaknya berfungsi jika Anda tidak memiliki bash 4. Jika Anda memiliki bash 4, maka pasti gunakan ekspansi brace! Lihat jawaban yang dipilih. Plug Shameless untuk memperbarui pesta Snow Leopard
milkypostman

Jawaban:

25

Coba ini:

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

Ini dikenal sebagai "ekspresi urutan" dan merupakan bagian dari fitur ekspansi brace Bash . Ini bekerja di Bash 3 dan 4.

Fitur kenaikan baru untuk Bash 4. Anda mungkin memiliki Bash 3.x.

Di Bash 4, Anda dapat melakukan:

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

Namun di Bash 3, Anda harus melakukan ini untuk mendapatkan hasil yang sama:

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

Bentuk yang sama bertambah satu:

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

Setiap angka dapat berupa variabel atau ekspresi. Namun, dalam ekspresi berurutan angka harus berupa konstanta

Berikut adalah contoh menggunakan formulir itu di file Anda:

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

Fitur baru lain dari ekspresi urutan dalam Bash 4 adalah kemampuan untuk memasukkan nol di depan. Ini berguna jika Anda ingin membuat (dan menggunakan) file bernomor yang dapat diurutkan dengan benar.

Dalam Bash 4:

touch file{001..010}.txt

akan membuat file bernama "file001.txt" melalui "file010.txt". Nama mereka akan disortir dalam urutan yang diharapkan. Tanpa nol di depan, "file10.txt" akan mengurutkan sebelum "file1.txt".

Untuk bekerja dengan file, Anda dapat menggunakan sintaks nol di depan yang sama:

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

Di Bash 3, jika Anda membutuhkan nol di depan, Anda harus memberi nilai sendiri:

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

The printfpernyataan akan tambahkan nilai i dengan nol terkemuka sehingga lebar adalah 3, misalnya ( "4" menjadi "004").

Edit:

Mengakomodasi ruang dalam nama file secara langsung:

$ 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
Dijeda sampai pemberitahuan lebih lanjut.
sumber
Terima kasih! Saya tidak tahu di mana ini sepanjang hidup saya. Satu hal yang saya tidak bisa mulai bekerja adalah bahwa kenaikan tampaknya tidak berfungsi di versi OSX dari bash. yaitu, saya tidak bisa mulai {1..10..2}bekerja di bash OSX saya.
milkypostman
Nah, itu penyebab Snow Leopard (karena alasan tertentu) menggunakan bash 3.1. Ini adalah masalah perangkat lunak.
milkypostman
@milkypostman: Fitur kenaikan dan nol di depan {01..10}adalah baru untuk Bash 4. Anda mungkin memiliki Bash 3.x. Jika Anda membutuhkan fitur kenaikan atau untuk menggunakan variabel untuk batas rentang, maka gunakan formulir ini: for ((i=1; i<=10; i+=2}(atau i++untuk menambah satu). Setiap angka dapat berupa variabel atau ekspresi. Kemudian, untuk menggunakan nilai di dalam forloop: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i` yang akan menambahkan nilai idengan memimpin nol sehingga lebarnya adalah 3, misalnya ("4" menjadi "004").
Dijeda sampai pemberitahuan lebih lanjut.
Dennis, apakah ada cara Anda akan memperbarui solusi Anda untuk memasukkan formulir alternatif. Menjadi komentar itu agak mengaburkan apa yang seharusnya saya dapatkan.
milkypostman
@milkypostman: Lihat jawaban saya yang diedit.
Dijeda sampai pemberitahuan lebih lanjut.