Bagaimana saya bisa menekan ruang di antara argumen yang dihasilkan selama ekspansi brace?

8

Saya menggunakan perintah berikut untuk membuat daftar URL yang ingin saya uji:

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Sayangnya, URL yang ditambahkan ke urls.txtmasing-masing memiliki ruang di depannya (kecuali yang pertama, tentu saja). Saya mengerti mengapa itu terjadi, dan saya sadar saya bisa menghilangkannya dengan menyalurkan sedekspresi, tetapi saya ingin tahu apakah ada cara untuk menekannya. (Ini mungkin terlihat konyol dan bertele-tele, tetapi itu tidak berbeda dengan preferensi yang dirasakan banyak orang karena tidak "menyalahgunakan kucing" .)

Saya mencoba kutip ganda untuk menekan pemisahan kata , tetapi itu juga menekan ekspansi brace, jadi itu adalah jalan keluar.

Saya mencoba mengubah IFS menjadi string kosong, tetapi tidak berhasil:

IFS='' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Juga tidak mengubahnya ke baris baru:

IFS='\n' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt
iconoclast
sumber
Apakah Anda menggunakan bash atau zsh?
Braiam
saat ini saya menggunakan bash (saya sedang bekerja) tetapi di laptop saya sendiri saya menggunakan zsh. Saya mengharapkan penjepit ekspansi untuk bekerja secara identik di keduanya, tapi mungkin itu tidak terjadi.
iconoclast
Dalam hal ini, jawaban Gnouc akan menjadi yang paling kompatibel dengan shell yang berbeda.
Braiam
Bukankah jawaban richard sama-sama kompatibel? (Ini juga memiliki keuntungan menjadi lebih sederhana, oleh karena itu saya tidak harus berhenti dan memikirkan bit fiddly pada saat saya ingin menggunakannya.) Di sisi lain, jawaban Gnouc juga sangat baik. Dan saya pikir saya belajar paling banyak dari jawaban glenn jackson. Jawaban Leiaz tampaknya paling sederhana dan paling elegan, tetapi tentu saja hanya zsh.
iconoclast

Jawaban:

8

Anda bisa menyimpan ekspansi brace dalam sebuah array, lalu mengeluarkannya dengan cara yang Anda pilih:

urls=( localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} )

Kemudian

printf "%s\n" "${urls[@]}"

atau

(IFS=$'\n'; echo "${urls[*]}")

Contoh gema terlihat aneh karena:

  1. itu dijalankan dalam subkulit (tanda kurung) jadi saya tidak mengubah nilai IFS saya saat ini.
  2. IFS perlu didefinisikan dalam perintah terpisah:
    • Ini tidak berfungsi: IFS=$'\n' echo "${urls[*]}"karena variabel akan diperluas sebelum variabel env baru berlaku
    • IFS perlu diatur sebelum Anda mulai memperluas variabel.

Perhatikan juga perbedaan kecil dalam indeks array dereferencing yang digunakan:

  • [@] dalam contoh printf untuk memperluas array menjadi kata-kata individual
  • [*] dalam contoh echo untuk memperluas array menjadi satu kata, dengan elemen yang dipisahkan oleh karakter pertama IFS
glenn jackman
sumber
Ini adalah panggilan yang sulit, tetapi saya memilih jawaban ini karena (1) tampaknya (AFAIK) menjadi yang paling dekat dengan tujuan yang ditekankan daripada hanya menghilangkan spasi, dan (2) saya belajar paling banyak dari itu (a tujuan lain dari pertanyaan saya).
iconoclast
16

Gunakan printfbuiltin:

$ printf %s\\n localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}
localhost:8080/reports/promos/130
localhost:8080/reports/promos/130.pdf
localhost:8080/reports/promos/130.xls
localhost:8080/reports/promos/130.xlsx
localhost:8080/reports/promos/130.csv
localhost:8080/reports/promos/130.preload
localhost:8080/reports/promos/130-unburdened
localhost:8080/reports/promos/130-unburdened.pdf
localhost:8080/reports/promos/130-unburdened.xls
localhost:8080/reports/promos/130-unburdened.xlsx
localhost:8080/reports/promos/130-unburdened.csv
localhost:8080/reports/promos/130-unburdened.preload
....
cuonglm
sumber
6

Ini ditandai zsh, jadi saya sarankan zsh builtin print:

print -l localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}

-l mencetak argumen pada baris yang berbeda.

Leiaz
sumber
+1 Terima kasih - senang tahu! Saya akan menggunakannya ketika saya sedang di zsh. Saya menandai itu hanya karena saya menggunakan keduanya dan keduanya mendukung ekspansi brace. (Saya tidak tahu apakah ada yang melakukannya, tetapi saya merasa ksh sangat membingungkan, jadi saya menjauh.)
iconoclast
3

Masalahnya adalah ekspansi brace menambah ruang, dan gema menambahkan baris baru. Jadi dengan menggunakan prinsip tanggung jawab tunggal, pegang baris baru secara terpisah.

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} | tr " " "\n"
ctrl-alt-delor
sumber
Saya pikir ini adalah pendekatan yang paling sederhana dan paling praktis
iconoclast
Tidak, ekspansi brace tidak menambah ruang, itu membuat beberapa argumen echo. Itu echoyang mencetak argumennya yang dipisahkan oleh spasi.
Stéphane Chazelas
Saya kira masalahnya terjadi karena echomemisahkan argumen dengan spasi dan baris baru dimasukkan tambahan sebelum setiap ruang alih-alih mengganti spasi (yang akan lebih masuk akal). Dari memori, xargsmemiliki masalah yang diketahui sangat mirip dengan yang satu ini (terutama dengan -0opsi)
sintaks