Saya memiliki file teks dengan format berikut:
keyword value
keyword value
...
Di mana kata kunci adalah satu kata dan nilai adalah segalanya sampai akhir baris. Saya ingin membaca file dari skrip shell, dengan cara nilai-nilai (tetapi bukan kata kunci) mengalami ekspansi shell.
Dengan sed mudah untuk mencocokkan kata kunci dan bagian nilai
input='
keyword value value
keyword "value value"
keyword `uname`
'
echo "$input"|sed -e 's/^\([^[:space:]]*\)[[:space:]]\(.*\)$/k=<\1> v=<\2>/'
yang menghasilkan
k=<keyword> v=<value value>
k=<keyword> v=<"value value">
k=<keyword> v=<`uname`>
tapi kemudian pertanyaannya adalah bagaimana saya bisa menanamkan perintah shell ke bagian pengganti dari ekspresi sed. Dalam hal ini saya ingin menjadi pengganti \1 `echo \2`
.
Jawaban:
Sed standar tidak dapat memanggil shell ( GNU sed memiliki ekstensi untuk melakukannya , jika Anda hanya peduli pada Linux yang tidak tertanam), jadi Anda harus melakukan beberapa pemrosesan di luar sed. Ada beberapa solusi; semua membutuhkan mengutip dengan cermat.
Tidak jelas bagaimana Anda ingin nilai diperluas. Misalnya, jika sebuah garis
mana dari berikut ini yang harus menjadi output?
Saya akan membahas beberapa kemungkinan di bawah ini.
cangkang murni
Anda bisa mendapatkan shell untuk membaca input baris demi baris dan memprosesnya. Ini adalah solusi paling sederhana, dan juga yang tercepat untuk file pendek. Ini adalah hal yang paling dekat dengan kebutuhan Anda "
echo \2
":read -r keyword value
set$keyword
ke kata pertama yang dibatasi spasi spasi, dan$value
ke seluruh baris dikurangi spasi spasi.Jika Anda ingin memperluas referensi variabel, tetapi tidak menjalankan perintah di luar pergantian perintah, masukkan ke
$value
dalam dokumen di sini . Saya menduga ini adalah apa yang sebenarnya Anda cari.sed disalurkan ke shell
Anda dapat mengubah input menjadi skrip shell dan mengevaluasinya. Sed sampai dengan tugas, meskipun itu tidak mudah. Mengikuti
echo \2
persyaratan " " Anda (perhatikan bahwa kami perlu menghindari tanda kutip tunggal dalam kata kunci):Pergi dengan dokumen di sini, kita masih perlu melarikan diri kata kunci (tetapi berbeda).
Ini adalah metode tercepat jika Anda memiliki banyak data: itu tidak memulai proses terpisah untuk setiap baris.
awk
Teknik yang sama kami gunakan dengan sed work dengan awk. Program yang dihasilkan jauh lebih mudah dibaca. Going with "
echo \2
":Menggunakan dokumen di sini:
sumber
Memiliki GNU
sed
Anda dapat menggunakan perintah berikut:Output yang mana:
dengan data input Anda.
Penjelasan:
Perintah sed menekan output reguler menggunakan
-n
opsi.-r
dilewatkan untuk menggunakan ekspresi reguler yang diperluas yang menyelamatkan kita dari lolosnya karakter khusus dalam pola tetapi tidak diperlukan.The
s
Perintah ini digunakan untuk mentransfer baris masukan ke dalam perintah:Kata kunci get mengutip nilai bukan. Saya meneruskan opsi
e
- yang khusus GNU - kes
perintah, yang memberitahu sed untuk mengeksekusi hasil substitusi sebagai perintah shell dan membaca hasilnya ke dalam buffer pola (Bahkan beberapa baris). Menggunakan opsip
after (!)e
Membuatsed
mencetak buffer pola setelah perintah dieksekusi.sumber
-n
danp
yaitused -r 's/([^ ]+) (.*)/echo "\1" \2\n/e' input
. Tapi terima kasih untuk ini! Saya tidak tahu tentange
opsi itu.e
opsi (diperkenalkan oleh GNU). Apakah itu masihsed
? :)Anda dapat mencoba pendekatan ini:
(jika saya benar niat Anda). Itu adalah memasukkan "proses" di awal setiap baris yang tidak kosong untuk menjadikannya skrip seperti:
untuk dievaluasi (
eval
) di mana proses adalah fungsi yang mencetak pesan yang diharapkan.sumber
Jika solusi non-sed dapat diterima, cuplikan PERL ini akan melakukan pekerjaan:
sumber
HANYA CIUMAN SINGKAT MURNI SED
Saya akan melakukan ini
dan itu bekerja.
sumber