GNU/Linux >> Belajar Linux >  >> Linux

Perluasan Pathname Bash/shell Untuk Mkdir, Touch Dll?

Jadi lakukan sesuatu seperti ini di bash dan sebagian besar shell lainnya tidak akan berfungsi untuk membuat banyak subdirektori atau file di dalam subdirektori…

mkdir */test
touch */hello.txt

Tentu saja ada banyak cara untuk benar-benar melakukan ini, yang saya sukai adalah menggunakan find bila memungkinkan daripada menggunakan for loop, terutama untuk keterbacaan.

Tapi pertanyaan saya adalah, mengapa hal di atas tidak berhasil?
Dari apa yang saya pahami itu karena file/path tujuan lengkap tidak ada tetapi pasti itu hal yang baik jika saya mencoba mkdir atau touch . Saya selalu pindah dan tidak pernah benar-benar mempertanyakannya.
Tapi apakah ada yang punya penjelasan yang layak untuk ini yang akan membantu saya memahaminya untuk selamanya?

Jawaban yang Diterima:

Poin yang mungkin Anda lewatkan – yang dialami banyak orang,
terutama jika mereka memiliki pengalaman dengan sistem operasi lain sebelum mereka menggunakan *nix
– adalah bahwa, di banyak OS lain, wildcard di baris perintah biasanya diteruskan ke perintah untuk memproses seperti yang terlihat cocok. Misalnya, di Prompt Perintah Windows,

rename *.jpeg *.jpg

Sedangkan, di *nix, untuk menyederhanakan tugas
programmer dari masing-masing perintah (mis., mv ), karakter pengganti
(bila tidak dikutip atau diloloskan) ditangani oleh shell,
dengan cara yang tidak bergantung pada antarmuka dan fungsionalitas
dari perintah yang menjadi argumen karakter pengganti.
Sebagian besar program yang menggunakan nama file sebagai argumen baris perintah mengharapkan file tersebut ada
(ya, mkdir dan touch pengecualian untuk aturan itu,
seperti mkfifo , mknod , dan, sebagian, cp , ln , mv , dan rename;
dan mungkin ada yang lain),
jadi tidak masuk akal jika shell memperluas wildcard
ke nama untuk file yang tidak ada.
Dan untuk cangkangnya (dan maksud saya setiap shell –
Bourne, bash, csh, fish, ksh, zsh, dll...) untuk menangani pengecualian secara berbeda
mungkin akan terlalu merepotkan.

Yang mengatakan, ada beberapa cara untuk mendapatkan hasil seperti yang Anda inginkan.
Jika Anda tahu apa yang akan diekspansi oleh wildcard,
dan itu tidak lama, Anda dapat membuatnya dengan ekspansi brace:

touch {red,orange,yellow,green,blue,indigo,violet}/rgb.txt

Solusi yang lebih umum:

sh -c 'for arg do mkdir -- "$arg"/test; done' -- *

Gilles membantu saya menemukan cara lain
untuk melakukannya di bash.

benbradley=(*)
mkdir "${benbradley[@]/%//test}"

Jelas benbradley hanya pengidentifikasi di sini; Anda dapat menggunakan nama apa saja
(mis., huruf apa saja).
Perlu beberapa kali percobaan untuk memperbaikinya, jadi izinkan saya menguraikannya:

  • identifier=value membuat variabel (skalar) bernama identifier (jika belum ada) dan memberikan nilai value untuk itu.
    Misalnya, G=Man .
    Anda dapat mereferensikan variabel skalar dengan $identifier;
    misalnya, $G , atau, lebih amannya, sebagai ${identifier} .
    Misalnya, $Gage dan $Gilla mungkin tidak terdefinisi,
    tetapi ${G}age adalah Manage dan ${G}illa adalah Manilla .
  • identifier=(value1 value2) membuat variabel array bernama identifier (jika belum ada) dan memberikan nilai yang tercantum padanya.
    Misalnya,
    spectrum=(red orange yellow green blue indigo violet)

    atau

      all_text_files=(*.txt)

      $name akan mereferensikan elemen pertama (dan karenanya cukup tidak berguna).
      Anda dapat mereferensikan elemen arbitrer sebagai ${name[subscript]};
      misalnya, ${spectrum[0]} adalah red dan ${spectrum[4]} adalah blue .
      Dan Anda dapat menggunakan ${name[@]} dan ${name[*]} untuk mereferensikan seluruh larik.

      Terkait:iPod touch dicuri dan perlu dicari?

      Jadi, ini dia berkeping-keping:

        "   ${   benbradley[@]   /   %   /   /test   }   "
        • ${parameter/pattern/string} memperluas ${parameter} dan menggantikan kecocokan
          terpanjang dari pattern dengan string .
        • Jika pattern dimulai dengan # ,
          harus cocok di awal nilai yang diperluas parameter .
          Jika pattern dimulai dengan % ,
          harus cocok di akhir nilai parameter .
          Dengan kata lain,
          %(the-rest_of_the_pattern)

          bertindak seperti

            (the-rest_of_the_regex)$

            (ya, sepertinya agak mundur).
            Jadi pattern itu hanya % seperti ekspresi reguler yang hanya $
            cocok dengan akhir string input (ruang pencarian).

            • Dan saya menggunakan string dari /test .
              Jadi ini menggantikan akhir parameter dengan /test (yaitu, itu menambahkan /test ke parameter).
            • Hal lain tentang ${parameter/pattern/string} yang tidak intuitif adalah selalu diakhiri dengan } .
              Tidak perlu, dan tidak bisa , akhiri dengan / ketiga .
              Oleh karena itu, sebuah / dalam string tidak dapat diartikan sebagai pembatas,
              dan oleh karena itu kita dapat memiliki string dari /test tanpa perlu keluar dari / .
            • Jika parameter adalah variabel array
              yang disubskrip dengan @ atau * ,
              operasi substitusi diterapkan ke setiap anggota larik secara bergantian.
            • Saat Anda mereferensikan array sebagai ${name[@]} (bukan ${name[*]} ) dan menempatkan hasilnya dalam tanda kutip ganda,
              Anda mempertahankan integritas elemen larik
              (yaitu, Anda mempertahankan spasi dan karakter khusus lainnya di dalamnya)
              tanpa menggabungkan elemen terpisah ke dalam satu kata yang panjang.

            Linux
            1. Apa shell favorit Anda untuk pekerjaan sysadmin?

            2. Mengapa pengguna mysql memiliki bash shell di /etc/passwd?

            3. Bagaimana Cara Membuat Lingkungan Shell yang Bersih Untuk Penggunaan Sementara?

            1. Mode IDE / Emacs untuk skrip Shell di Bash/Sh, dll

            2. Skrip Bash Shell - Periksa bendera dan ambil nilainya

            3. Cakupan variabel untuk skrip bash shell dan fungsi dalam skrip

            1. Alasan Bash Shell Tidak Memperingatkan Anda Tentang Aritmatika Overflow Dll?

            2. 12 Contoh Bash For Loop untuk Scripting Shell Linux Anda

            3. Cara menonaktifkan penyelesaian otomatis (penyelesaian tab) di bash shell