The bash
cara adalah baik, tetapi bagaimana jika Anda bekerja dengan shell yang tidak mendukung ekspansi penjepit keriting? touch file{1..10}
misalnya, tidak bekerja untuk saya mksh
. Berikut tiga cara alternatif yang berfungsi terlepas dari cangkang.
seq
Pendekatan yang lebih netral shell adalah menggabungkan seq
perintah untuk menghasilkan urutan angka yang diformat dengan printf
opsi, dan meneruskannya ke xargs
perintah. Sebagai contoh,
$ ls -l
total 0
$ seq -f "%04.0f" 10 | xargs -I "{}" touch bspl"{}".c
$ ls
bspl0002.c bspl0004.c bspl0006.c bspl0008.c bspl0010.c
bspl0001.c bspl0003.c bspl0005.c bspl0007.c bspl0009.c
Perl
Tentu saja, Perl, sebagai alat * nix yang lebar, dapat melakukannya juga. Perintah one-liner spesifik yang kita miliki di sini adalah sebagai berikut:
perl -le 'do { $var=sprintf("%s%04d.c",$ARGV[0],$_ ); open(my $fh, ">", $var);close($fh) } for $ARGV[1] .. $ARGV[2]' bslp 1 5
Secara efektif apa yang terjadi di sini adalah kita menentukan 3 argumen baris perintah: awalan nama file, indeks awal, dan indeks akhir. Kemudian kita gunakan do { } for $ARGV[1] .. $ARGV[2]
untuk beralih ke kisaran angka tertentu. Katakanlah, $ARGV[1]
adalah 5 dan $ARGV[2]
9, kami akan mengulangi lebih dari 5,6,7,8 dan 9.
Apa yang terjadi pada setiap iterasi dalam kurung kurawal? kita mengambil setiap angka yang ditentukan dengan $_
, dan menggunakan sprintf()
fungsi membuat string m yang menyambungkan awalan (argumen baris perintah pertama, $ARGV[0]
) dan nomor yang diberikan, tetapi mengisi angka dengan 4 nol (yang dilakukan dengan- printf
gaya pemformatan, %04d
bagian), dan lampirkan .c
suffix. Sebagai hasil pada setiap iterasi kita membuat nama seperti bspl0001.c
.
Secara open(my $fh, ">", $var);close($fh)
efektif bertindak sebagai touch
perintah, membuat file dengan nama yang ditentukan.
Meskipun sedikit panjang, performanya cukup baik, dengan cara yang mirip dengan skrip python Jacob Vlijm. Itu juga dapat dikonversi ke skrip untuk dibaca jika diinginkan, seperti:
#!/usr/bin/env perl
use strict;
use warnings;
for my $i ( $ARGV[1] .. $ARGV[2] ) {
my $var=sprintf("%s%04d.c",$ARGV[0],$i );
open(my $fh, ">", $var) or die "Couldn't open " . $var ;
close($fh) or die "Couldn't close " . $var ;
}
Mari kita coba ini. Pertama, satu-liner:
$ ls -l
total 0
$ perl -le 'do { $var=sprintf("%s%04d.c",$ARGV[0],$_ ); open(my $fh, ">", $var);close($fh) } for $ARGV[1] .. $ARGV[2]' bslp 1 5
$ ls -l
total 0
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:36 bslp0001.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:36 bslp0002.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:36 bslp0003.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:36 bslp0004.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:36 bslp0005.c
Dan sekarang skripnya:
$ ls -l
total 4
-rwxrwxr-x 1 xieerqi xieerqi 244 2月 5 23:57 touch_range.pl*
$ ./touch_range.pl bspl 1 5
$ ls -l
total 4
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:58 bspl0001.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:58 bspl0002.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:58 bspl0003.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:58 bspl0004.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月 5 23:58 bspl0005.c
-rwxrwxr-x 1 xieerqi xieerqi 244 2月 5 23:57 touch_range.pl*
awk
Pendekatan lain akan dengan awk
, menjalankan loop for, mengarahkan ke file tertentu. Pendekatannya mirip dengan perl one-liner dengan argumen command-line. Walaupun awk
terutama merupakan utilitas pemrosesan teks, masih dapat melakukan beberapa pemrograman sistem yang keren.
$ awk 'BEGIN{for(i=ARGV[2];i<=ARGV[3];i++){fd=sprintf("%s%04d.c",ARGV[1],i); printf "" > fd;close(fd)}}' bslp 1 5