GNU/Linux >> Belajar Linux >  >> Linux

Cara menulis loop di Bash

Alasan umum orang ingin mempelajari shell Unix adalah untuk membuka kekuatan pemrosesan batch. Jika Anda ingin melakukan beberapa rangkaian tindakan pada banyak file, salah satu cara untuk melakukannya adalah dengan membuat perintah yang mengulangi file tersebut. Dalam terminologi pemrograman, ini disebut kontrol eksekusi, dan salah satu contoh paling umum adalah untuk lingkaran.

Sebuah untuk loop adalah resep yang merinci tindakan apa yang Anda ingin komputer Anda lakukan untuk setiap objek data (seperti file) yang Anda tentukan.

Perulangan for klasik

Terminal Linux

  • 7 emulator terminal teratas untuk Linux
  • 10 alat baris perintah untuk analisis data di Linux
  • Unduh Sekarang:lembar contekan SSH
  • Lembar contekan perintah Linux tingkat lanjut
  • Tutorial baris perintah Linux

Loop yang mudah untuk dicoba adalah loop yang menganalisis kumpulan file. Ini mungkin bukan loop yang berguna, tetapi ini adalah cara yang aman untuk membuktikan kepada diri sendiri bahwa Anda memiliki kemampuan untuk menangani setiap file dalam direktori satu per satu. Pertama, buat lingkungan pengujian sederhana dengan membuat direktori dan menempatkan beberapa salinan dari beberapa file ke dalamnya. File apa pun pada awalnya akan berfungsi, tetapi contoh selanjutnya memerlukan file grafik (seperti JPEG, PNG, atau serupa). Anda dapat membuat folder dan menyalin file ke dalamnya menggunakan pengelola file atau di terminal:

$ contoh mkdir
        $ cp ~/Pictures/vacation/*.{png,jpg} contoh

Ubah direktori ke folder baru Anda, lalu daftarkan file di dalamnya untuk mengonfirmasi bahwa lingkungan pengujian Anda sesuai dengan yang Anda harapkan:

$ contoh cd
$ ls -1
cat.jpg
design_maori.png
otago.jpg
waterfall.png

Sintaks untuk mengulang setiap file satu per satu dalam satu lingkaran adalah:buat variabel (f untuk file, misalnya). Kemudian tentukan kumpulan data yang Anda ingin variabel untuk digilir. Dalam hal ini, putar semua file di direktori saat ini menggunakan * karakter wildcard (* wildcard cocok dengan semuanya ). Kemudian akhiri klausa pengantar ini dengan titik koma (; ).

$ for f in * ; 

Bergantung pada preferensi Anda, Anda dapat memilih untuk menekan Kembali di sini. Shell tidak akan mencoba mengeksekusi loop sampai sintaksisnya selesai.

Selanjutnya, tentukan apa yang Anda inginkan terjadi dengan setiap iterasi loop. Untuk mempermudah, gunakan file perintah untuk mendapatkan sedikit data tentang setiap file, yang diwakili oleh f variabel (tetapi diawali dengan $ untuk memberi tahu Shell untuk menukar nilai variabel dengan apa pun yang ada di variabel saat ini):

do file $f ; 

Hentikan klausa dengan titik koma lain dan tutup loop:

done 

Tekan Kembali untuk memulai siklus shell melalui semuanya di direktori saat ini. untuk loop menetapkan setiap file, satu per satu, ke variabel f dan jalankan perintah Anda:

$ untuk f di *; lakukan
       > file $f;
       > selesai
        cat.jpg:Data gambar JPEG, standar EXIF ​​2.2
        design_maori.png:Data gambar PNG, 4608 x 2592, 8-bit /color RGB, non-interlaced
        otago.jpg:Data gambar JPEG, standar EXIF ​​2.2
        waterfall.png:Data gambar PNG, 4608 x 2592, RGB 8-bit/warna, non-interlaced

Anda juga dapat menulisnya dengan cara ini:

$ untuk f di *; lakukan file $f; selesai
        cat.jpg:Data gambar JPEG, standar EXIF ​​2.2
        design_maori.png:Data gambar PNG, 4608 x 2592, RGB 8-bit/warna, non-interlaced
        otago.jpg:Data gambar JPEG, standar EXIF ​​2.2
        waterfall.png:Data gambar PNG, 4608 x 2592, RGB 8-bit/warna, non-interlaced

Format multi-baris dan satu baris sama untuk shell Anda dan menghasilkan hasil yang sama persis.

Contoh praktis

Berikut adalah contoh praktis tentang bagaimana sebuah loop dapat berguna untuk komputasi sehari-hari. Asumsikan Anda memiliki koleksi foto liburan yang ingin Anda kirimkan ke teman. File foto Anda sangat besar, membuatnya terlalu besar untuk dikirim melalui email dan tidak nyaman untuk diunggah ke layanan berbagi foto Anda. Anda ingin membuat versi web yang lebih kecil dari foto Anda, tetapi Anda memiliki 100 foto dan tidak ingin menghabiskan waktu untuk mengurangi setiap foto, satu per satu.

Pertama, instal ImageMagick perintah menggunakan manajer paket Anda di Linux, BSD, atau Mac. Misalnya, di Fedora dan RHEL:

$ sudo dnf install ImageMagick 

Di Ubuntu atau Debian:

$ sudo apt install ImageMagick 

Di BSD, gunakan port atau pkgsrc. Di Mac, gunakan Homebrew atau MacPorts.

Setelah Anda menginstal ImageMagick, Anda memiliki serangkaian perintah baru untuk beroperasi pada foto.

Buat direktori tujuan untuk file yang akan Anda buat:

$ mkdir tmp 

Untuk memperkecil setiap foto menjadi 33% dari ukuran aslinya, coba loop ini:

$ for f in * ; do convert $f -scale 33% tmp/$f ; done 

Kemudian lihat di tmp folder untuk melihat foto Anda yang diskalakan.

Anda dapat menggunakan sejumlah perintah dalam satu lingkaran, jadi jika Anda perlu melakukan tindakan kompleks pada sekumpulan file, Anda dapat menempatkan seluruh alur kerja Anda di antara lakukan dan selesai pernyataan untuk lingkaran. Misalnya, Anda ingin menyalin setiap foto yang diproses langsung ke direktori foto bersama di host web Anda dan menghapus file foto dari sistem lokal Anda:

$ untuk f di *; lakukan 
    konversi $f -scale 33% tmp/$f
    scp -i seth_web tmp/$f [email protected]:~/public_html
    trash tmp/$f;
  selesai

Untuk setiap file yang diproses oleh untuk loop, komputer Anda secara otomatis menjalankan tiga perintah. Ini berarti jika Anda hanya memproses 10 foto dengan cara ini, Anda menghemat 30 perintah dan mungkin setidaknya beberapa menit.

Membatasi loop Anda

Sebuah loop tidak selalu harus melihat setiap file. Anda mungkin ingin memproses hanya file JPEG di direktori contoh Anda:

$ untuk f di *.jpg; lakukan konversi $f -scale 33% tmp/$f; selesai
$ ls -m tmp
cat.jpg, otago.jpg

Atau, alih-alih memproses file, Anda mungkin perlu mengulangi tindakan beberapa kali. Sebuah untuk variabel loop ditentukan oleh data apa pun yang Anda berikan, sehingga Anda dapat membuat loop yang berulang pada angka alih-alih file:

$ untuk n dalam {0..4}; lakukan echo $n; selesai
0
1
2
3
4

Lebih banyak pengulangan

Anda sekarang cukup tahu untuk membuat loop Anda sendiri. Sampai Anda merasa nyaman dengan pengulangan, gunakan pada salinan dari file yang ingin Anda proses dan, sesering mungkin, gunakan perintah dengan perlindungan bawaan untuk mencegah Anda merusak data dan membuat kesalahan yang tidak dapat diperbaiki, seperti secara tidak sengaja mengganti nama seluruh direktori file dengan nama yang sama, masing-masing menimpa yang lain .

Untuk untuk tingkat lanjut loop topik, baca terus.

Tidak semua shell adalah Bash

untuk kata kunci dibangun ke dalam shell Bash. Banyak shell serupa menggunakan kata kunci dan sintaks yang sama, tetapi beberapa shell, seperti tcsh, menggunakan kata kunci yang berbeda, seperti foreach , sebagai gantinya.

Di tcsh, sintaksnya serupa dalam semangat tetapi lebih ketat daripada Bash. Dalam contoh kode berikut, jangan ketik string foreach? di baris 2 dan 3. Ini adalah prompt sekunder yang memperingatkan Anda bahwa Anda masih dalam proses membangun loop Anda.

$ foreach f (*)
foreach? file $f
foreach? end
cat.jpg:Data gambar JPEG, standar EXIF ​​2.2
design_maori.png:Data gambar PNG, 4608 x 2592, RGB 8-bit/warna, non-interlaced
otago.jpg:Data gambar JPEG, standar EXIF ​​2.2
waterfall.png:Data gambar PNG, 4608 x 2592, RGB 8-bit/warna, non-interlaced

Di tcsh, keduanya foreach dan berakhir harus muncul sendiri pada baris terpisah, jadi Anda tidak dapat membuat untuk loop pada satu baris yang Anda bisa dengan Bash dan shell serupa.

Untuk loop dengan perintah find

Secara teori, Anda dapat menemukan cangkang yang tidak menyediakan untuk fungsi loop, atau Anda mungkin lebih suka menggunakan perintah yang berbeda dengan fitur tambahan.

menemukan perintah adalah cara lain untuk mengimplementasikan fungsionalitas untuk loop, karena menawarkan beberapa cara untuk menentukan cakupan file mana yang akan disertakan dalam loop Anda serta opsi untuk pemrosesan Paralel.

menemukan perintah dimaksudkan untuk membantu Anda menemukan file di hard drive Anda. Sintaksnya sederhana:Anda memberikan jalur lokasi yang ingin Anda telusuri, dan menemukan menemukan semua file dan direktori:

$ temukan . 
.
./cat.jpg
./design_maori.png
./otago.jpg
./waterfall.png

Anda dapat memfilter hasil pencarian dengan menambahkan beberapa bagian nama:

$ temukan . -nama "*jpg"
./cat.jpg
./otago.jpg

Hal hebat tentang menemukan adalah bahwa setiap file yang ditemukan dapat dimasukkan ke dalam loop menggunakan -exec bendera. Misalnya, untuk memperkecil hanya foto PNG di direktori contoh Anda:

$ temukan . -name "*png" -exec convert {} -scale 33% tmp/{} \;
$ ls -m tmp
design_maori.png, waterfall.png

Di -exec klausa, karakter kurung {} mendukung item apa pun yang ditemukan sedang diproses (dengan kata lain, file apa pun yang diakhiri dengan PNG yang telah ditemukan, satu per satu). -exec klausa harus diakhiri dengan titik koma, tetapi Bash biasanya mencoba menggunakan titik koma untuk dirinya sendiri. Anda "melarikan diri" dari titik koma dengan garis miring terbalik (\; ) sehingga menemukan tahu untuk memperlakukan titik koma itu sebagai karakter pengakhirannya.

menemukan perintah sangat baik dalam apa yang dilakukannya, dan kadang-kadang bisa terlalu bagus. Misalnya, jika Anda menggunakannya kembali untuk menemukan file PNG untuk proses foto lain, Anda akan mendapatkan beberapa kesalahan:

$ temukan . -name "*png" -exec convert {} -flip -flop tmp/{} \; 
convert:tidak dapat membuka gambar `tmp/./tmp/design_maori.png':
Tidak ada file atau direktori @ error/blob.c/OpenBlob/2643.
...

Tampaknya menemukan telah menemukan semua file PNG—tidak hanya yang ada di direktori Anda saat ini (. ) tetapi juga yang Anda proses sebelumnya dan ditempatkan di tmp . Anda subdirektori. Dalam beberapa kasus, Anda mungkin ingin menemukan untuk mencari direktori saat ini ditambah semua direktori lain di dalamnya (dan semua direktori di itu ). Ini bisa menjadi alat pemrosesan rekursif yang kuat, terutama dalam struktur file yang kompleks (seperti direktori artis musik yang berisi direktori album yang berisi file musik), tetapi Anda dapat membatasinya dengan -maxdepth pilihan.

Untuk menemukan hanya file PNG di direktori saat ini (tidak termasuk subdirektori):

$ find . -maxdepth 1 -name "*png" 

Untuk menemukan dan memproses file di direktori saat ini ditambah tingkat subdirektori tambahan, tambahkan kedalaman maksimum sebesar 1:

$ find . -maxdepth 2 -name "*png" 

Standarnya adalah turun ke semua subdirektori.

Berulang-ulang untuk kesenangan dan keuntungan

Semakin banyak Anda menggunakan loop, semakin banyak waktu dan upaya yang Anda hemat, dan semakin besar tugas yang dapat Anda tangani. Anda hanya satu pengguna, tetapi dengan pengulangan yang dipikirkan dengan matang, Anda dapat membuat komputer Anda bekerja keras.

Anda dapat dan harus memperlakukan perulangan seperti perintah lainnya, menjaganya tetap dekat ketika Anda perlu mengulangi satu atau dua tindakan pada beberapa file. Namun, ini juga merupakan pintu gerbang yang sah untuk pemrograman yang serius, jadi jika Anda harus menyelesaikan tugas yang kompleks pada sejumlah file, luangkan waktu sejenak dari hari Anda untuk merencanakan alur kerja Anda. Jika Anda dapat mencapai tujuan Anda pada satu file, maka bungkus proses berulang itu dalam untuk loop relatif sederhana, dan satu-satunya "pemrograman" yang diperlukan adalah pemahaman tentang cara kerja variabel dan pengaturan yang cukup untuk memisahkan file yang belum diproses dari file yang diproses. Dengan sedikit latihan, Anda dapat berpindah dari pengguna Linux ke pengguna Linux yang tahu cara menulis loop, jadi keluarlah dan buat komputer Anda bekerja untuk Anda!


Linux
  1. Bagaimana Cara Men-debug Skrip Bash?

  2. Bagaimana Menghentikan Skrip Loop Bash Di Terminal?

  3. Bagaimana Cara Mendeteksi Bash>=4.0?

  1. Bagaimana cara menulis beberapa baris string menggunakan Bash dengan variabel?

  2. Bagaimana cara menulis integer ke file biner menggunakan Bash?

  3. Cara mendapatkan status keluar satu lingkaran di bash

  1. Cara menggunakan perintah riwayat Bash

  2. Cara Berkomentar di Bash

  3. Cara Menulis Skrip Bash dengan Contoh