Saya kadang-kadang menjalankan baris perintah bash seperti ini:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
Untuk menjalankan some_command
beberapa kali berturut-turut - 10 kali dalam hal ini.
Seringkali some_command
benar-benar sebuah rantai perintah atau saluran pipa.
Apakah ada cara yang lebih ringkas untuk melakukan ini?
let ++n
alih-alihn=$((n+1))
(3 karakter kurang)zsh
milikirepeat 10 do some_command; done
.sh: 1: [[: not found
.Jawaban:
Atau sebagai one-liner bagi mereka yang ingin menyalin dan menempel dengan mudah:
sumber
for (n=0;n<k;n++))
mungkin lebih baik; Saya menduga{1..k}
akan memunculkan string dengan semua bilangan bulat yang dipisahkan oleh spasi.n=15;for i in $(seq -f "%02g" ${n});do echo $i; done 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
Menggunakan konstanta:
Menggunakan variabel (dapat menyertakan ekspresi matematika):
sumber
x=10
for ((n=0; n < $x; n++));
for run in {1..10}; do echo "on run $run"; done
n
sudah diatur ke nilai tertentu?for (( ; n<10; n++ ))
doesnt work / edit: terbaik mungkin menggunakan salah satu dari jawaban yang lain sepertiwhile (( n++...
satuCara sederhana lain untuk meretasnya:
jalankan gema 20 kali.
Perhatikan bahwa
seq 20 | xargs -Iz echo "Hi there z"
akan menampilkan:sumber
seq 20
)seq 20 | xargs -I{} echo "Hi there {}"
z
ini bukan placeholder yang baik karena sangat umum sehingga bisa menjadi teks biasa dalam teks perintah. Gunakan{}
akan lebih baik.seq
? jadi itu hanya akan mencetakHi there
20 kali (tidak ada nomor)? EDIT: cukup gunakan-I{}
dan kemudian tidak ada{}
dalam perintahIIIII
maka itu terlihat bagus misalnya:seq 20 | xargs -IIIIII timeout 10 yourCommandThatHangs
Jika Anda menggunakan shell zsh:
Di mana 10 adalah berapa kali perintah akan diulang.
sumber
repeat 10 { !! }
Menggunakan GNU Parallel yang bisa Anda lakukan:
Jika Anda tidak ingin nomor sebagai argumen dan hanya menjalankan satu pekerjaan sekaligus:
Tonton video intro untuk perkenalan cepat: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Ikuti tutorialnya ( http://www.gnu.org/software/parallel/parallel_tutorial.html ). Anda perintah baris dengan mencintaimu karenanya.
sumber
-j1 -N0
yang mematikan paralelisme ????some_command
1000 kali secara serial tanpa argumen? Dan: Bisakah Anda menyatakan lebih pendek dari ituparallel -j1 -N0 some_command ::: {1..1000}
?repeat.sh repeatcount some_command
. Untuk implementasi dalam skrip shell yang mungkin saya gunakanparallel
, jika sudah diinstal pada mesin (mungkin tidak akan). Atau saya mungkin condong ke xargs karena itu tampaknya paling cepat ketika tidak ada pengalihan diperlukan olehsome_command
.parallel -N0 -j1 --retries 4 --results outputdir/ some_command
Fungsi sederhana dalam file konfigurasi bash (
~/.bashrc
sering) dapat bekerja dengan baik.Sebut saja seperti ini.
sumber
do ${*:2}
saya menambahkan evaldo eval ${*:2}
untuk memastikan bahwa itu akan bekerja untuk menjalankan perintah yang tidak dimulai dengan executable. Misalnya, jika Anda ingin mengatur variabel lingkungan sebelum menjalankan perintah likeSOME_ENV=test echo 'test'
.xargs
adalah cepat :Pada Linux 64-bit modern, berikan:
Ini masuk akal, karena
xargs
perintah adalah proses asli tunggal yang memunculkan/usr/bin/true
perintah beberapa kali, bukanfor
danwhile
loop yang semuanya ditafsirkan dalam Bash. Tentu saja ini hanya berfungsi untuk satu perintah; jika Anda perlu melakukan beberapa perintah dalam setiap iterasi, itu akan sama cepatnya, atau mungkin lebih cepat, daripada beralihsh -c 'command1; command2; ...'
ke xargsThe
-P1
juga bisa berubah menjadi, katakanlah,-P8
untuk menelurkan 8 proses secara paralel untuk mendapatkan dorongan besar lain dalam kecepatan.Saya tidak tahu mengapa paralel GNU sangat lambat. Saya akan berpikir itu akan sebanding dengan xargs.
sumber
Bentuk lain dari contoh Anda:
sumber
Untuk satu, Anda dapat membungkusnya dalam suatu fungsi:
Sebut saja seperti:
sumber
tr
sini menyesatkan dan bekerja pada outputmanytimes
, bukanecho
. Saya pikir Anda harus menghapusnya dari sampel.xargs dan seq akan membantu
pandangan :
sumber
Perhatikan garis bawah alih-alih menggunakan variabel.
sumber
_
adalah nama variabel.Jika Anda OK melakukannya secara berkala, Anda dapat menjalankan perintah berikut untuk menjalankannya setiap 1 detik tanpa batas. Anda dapat menempatkan cek khusus lainnya untuk menjalankannya dan beberapa kali.
watch -n 1 some_command
Jika Anda ingin mendapatkan konfirmasi visual tentang perubahan, tambahkan
--differences
sebelumls
perintah.Menurut halaman manual OSX, ada juga
Halaman manual Linux / Unix dapat ditemukan di sini
sumber
Saya diselesaikan dengan loop ini, di mana pengulangan adalah bilangan bulat yang mewakili nomor loop
sumber
Namun jawaban lain: Gunakan ekspansi parameter pada parameter kosong:
Diuji pada Centos 7 dan MacOS.
sumber
Semua jawaban yang ada tampaknya membutuhkan
bash
, dan tidak berfungsi dengan BSD UNIX standar/bin/sh
(misalnya,ksh
pada OpenBSD ).Kode di bawah ini dapat digunakan pada BSD:
sumber
Agak naif tapi ini yang biasanya saya ingat di atas kepala saya:
Sangat mirip dengan jawaban @ joe-koberg. Ini lebih baik terutama jika Anda membutuhkan banyak pengulangan, lebih sulit bagi saya untuk mengingat sintaks lain karena dalam beberapa tahun terakhir saya tidak menggunakan
bash
banyak. Maksudku bukan untuk skrip setidaknya.sumber
File skrip
dan output di bawah ini
sumber
Bagaimana dengan bentuk alternatif yang
for
disebutkan dalam (Bashref) Looping Constructs ?sumber
Untuk loop mungkin cara yang tepat untuk melakukannya, tetapi di sini ada alternatif yang menyenangkan:
echo -e {1..10}"\n" |xargs -n1 some_command
Jika Anda memerlukan nomor iterasi sebagai parameter untuk permohonan Anda, gunakan:
echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @
Sunting: Sudah benar dikomentari bahwa solusi yang diberikan di atas akan berfungsi dengan baik hanya dengan menjalankan perintah sederhana (tidak ada pipa, dll). Anda selalu dapat menggunakan
sh -c
untuk melakukan hal-hal yang lebih rumit, tetapi tidak sepadan.Metode lain yang saya gunakan biasanya adalah fungsi berikut:
rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}
sekarang Anda dapat menyebutnya sebagai:
rep 3 10 echo iteration @
Dua angka pertama memberikan kisaran. The
@
akan diterjemahkan ke nomor iterasi. Sekarang Anda dapat menggunakan ini dengan pipa juga:rep 1 10 "ls R@/|wc -l"
dengan memberi Anda jumlah file dalam direktori R1 .. R10.
sumber
rep 1 2 touch "foo @"
tidak akan membuat dua file "foo 1" dan "foo 2"; melainkan membuat tiga file "foo", "1", dan "2". Mungkin ada cara untuk mendapatkan kutipan yang benar menggunakanprintf
dan%q
, tapi itu akan sulit untuk mendapatkan urutan kata-kata sewenang-wenang yang dikutip dengan benar ke dalam satu string untuk diteruskansh -c
.rep
dalam Anda.bashrc
, doa selanjutnya menjadi jauh lebih ringkas.