Menggunakan ekspansi parameter untuk menghasilkan daftar argumen untuk `mkdir -p`


10

Saya punya sesuatu seperti ini:

% ls -1dF /tmp/foo/*
/tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/
/tmp/foo/002e34c2218f2c86fefd2876f0e5c2559c5fb3c4/
/tmp/foo/00b483576791bab751e6cb7ee0a7143af43a8069/
.
.
.
/tmp/foo/fedd0f7b545e7ae9600142656756456bc16874d3/
/tmp/foo/ff51ac87609012137cfcb02f36624f81cdc10788/
/tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/

Saya ingin membuat direktori di barbawah setiap subdirektori di bawah foo.

Jika saya mencoba melakukan ini dengan

% mkdir -p /tmp/foo/*/bar

... Saya mendapatkan kesalahan

zsh: no matches found: /tmp/foo/*/bar

(Kalau dipikir-pikir, saya bisa mengerti alasan kesalahan itu.)

Saya tahu bahwa saya dapat memecahkan masalah asli dengan for-loop, tapi saya ingin tahu apakah zshmendukung beberapa bentuk ekspansi parameter yang akan menghasilkan argumen yang diinginkan untuk satu permintaan mkdir -p. TKI, ekspansi parameter setara dengan "tambahkan /barke setiap awalan yang dihasilkan oleh ekspansi /tmp/foo/*", menghasilkan

% mkdir -p /tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/bar ... /tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/bar

Jawaban:


13
setopt histsubstpattern extendedglob
mkdir -p /tmp/foo/*(#q/:s_%_/bar_)

Ini adalah globbing yang diperluas yang memiliki quiet glob flag yang menggunakan kualifikasi glob untuk mencocokkan hanya direktori dan pengubah untuk melakukan spengganti (menggunakan %karakter pola yang hanya tersedia dalam mode pola substitusi sejarah ) yang menambahkan string ke setiap kata.

man zshexpn

Wow, saya terkesan. Saya bahkan menemukan semuanya di halaman manual yang Anda tentukan.
Wildcard

1
Perhatikan bahwa Poster Asli yang ditentukan mkdir -p, yang akan memiliki efek yang sedikit berbeda dari perintah Anda untuk tidak melakukan kesalahan jika beberapa direktori tersebut sudah memiliki barsubdirektori. Poin kecil tapi perlu diperhatikan di sini. :)
Wildcard

1
Cara lain adalah dengan menggunakan ekspansi array melalui ${^spec}dan menambahkan barke setiap elemen dari apa pun yang /tmp/foo/*(/)meluas ke: set -- /tmp/foo/*(/)thenmkdir -p -- "${^@}/bar"
don_crissti

5

Tentu - gunakan satu lingkaran

for n in /tmp/foo/*; do mkdir "$n/bar";done

gumpalan digunakan untuk memperluas daftar item yang ada , bukan hal-hal yang belum dibuat.


Maaf, saya khawatir pertanyaan saya tidak dinyatakan dengan jelas. Saya akan menjelaskannya.
kjo

2
Ini tidak menjawab jika zshdapat memperluas gumpalan dan menambahkan teks dengan sintaks tunggal — tapi saya pikir itu kemungkinan satu-satunya cara untuk melakukan apa yang Anda inginkan, @kjo.
Wildcard

4

Jika direktori berada dalam array, Anda dapat menggunakan ${^...}bentuk ekspansi.

a=(/tmp/foo/*/)
mkdir -p ${^a}bar

0

Anda dapat menggunakan finddan xargsmelakukannya:

find /tmp/foo -maxdepth 1 -mindepth 1 -type d | xargs -i echo mkdir -p {}/bar

yang menggunakan -maxdepth 1dan -mindepth 1untuk mencegah pembuatan bardalam subdirektori target, dan /tmp/foomasing-masing dengan sendirinya. type dmembuatnya hanya mempertimbangkan direktori.

Anda harus menghapus echountuk melakukan tindakan yang sebenarnya, jika tidak echohanya akan mencetak baris untuk dieksekusi. Anda juga dapat melampirkannya di subtitusi suka $()mengeksekusi.

Manual mengatakan xargs -isudah usang, tetapi saya tidak menemukan alternatif lain yang sama praktisnya, sehingga masih bisa digunakan selama beberapa tahun ... Anda dapat menggantinya -idengan yang -I'{}'terbaru.


Jawaban ini dan yang berikutnya terlihat bagus untuk saya. Dapatkah seseorang menjelaskan mengapa mereka harus dipilih? Suara down baik-baik saja, tetapi bagaimana kita bisa belajar jika tidak ada alasan yang diberikan?
Joe

Ini adalah alternatif yang berfungsi tidak melakukan apa pun kecuali apa yang diminta OP. Mengalahkan saya.
loa_in_

Saya pikir itu semacam bias bahwa jawaban pasti memiliki jawaban yang buruk pada mereka, jadi prasangka mengambil itu merusak reputasi saya.
loa_in_

Saya tidak suka suara yang tidak dapat dijelaskan, tapi saya belum melihat bias semacam itu. Biasanya, jawaban "buruk" (yang saya mengerti) sebenarnya buruk.
Joe

0

@loa_in_ memiliki sebagian besar, tetapi findoutput perpipaan cenderung palsu.

find /tmp/foo -maxdepth 1 -mindepth 1 -type d -exec mkdir {}/bar \;

Saya hanya menggunakan xargsdengan alat yang berbeda yang tidak memiliki -execalternatif, jadi saya menggunakan pendekatan saya karena bekerja dengan semuanya secara merata.
loa_in_
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.