Menggunakan sed untuk menghapus braket persegi pembukaan dan penutupan di sekitar string

18

Saya menjalankan perintah ini dalam bash shell di Ubuntu 12.04.1 LTS. Saya mencoba untuk menghapus kedua karakter [dan ]dalam satu gerakan, yaitu tanpa harus menyalurkan untuk kedua kalinya.

Saya tahu tanda kurung siku memiliki arti khusus dalam regex jadi saya melarikan diri dengan menambahkan backslash. Hasil yang saya harapkan hanyalah string 123tetapi tanda kurung tetap dan saya ingin tahu mengapa!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]
Xhantar
sumber
Apa yang saya coba akhirnya capai adalah untuk menetapkan apa pun di antara tanda kurung siku ke variabel bash untuk digunakan di tempat lain dalam skrip bash saya, jadi jika ada cara yang lebih baik untuk mencapai itu (dengan menggunakan awk, mungkin?), Tolong beri tahu saya .
Xhantar
2
Hanya menambahkan sebagai komentar: Anda dapat menggunakan fitur bash's PE seperti di: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Valentin Bajrami
1
@ val0x00ff - Substitusi bash murni .. terima kasih! :) Mempelajari sesuatu yang baru.
Xhantar

Jawaban:

24

Ini mudah, jika Anda mengikuti manual dengan hati-hati: semua anggota di dalam kelas karakter kehilangan makna khusus (dengan beberapa pengecualian). Dan] kehilangan arti khusus jika ditempatkan pertama dalam daftar. Mencoba:

$ echo '[123]' | sed 's/[][]//g'
123
$

Ini mengatakan:

  1. dalam luar [kurung], ganti salah satu karakter disertakan, yaitu:
    • ] dan
    • [
  2. ganti mereka dengan string kosong - maka string pengganti kosong //,
  3. ganti di mana - mana ( secara global ) - maka final g.

Sekali lagi, ] harus menjadi yang pertama di kelas setiap kali dimasukkan.

Saparagus
sumber
11

Saya tidak yakin mengapa itu tidak berhasil tetapi ini berhasil:

echo '[123]' | sed 's/\(\[\|\]\)//g'

atau ini:

echo '[123]' | sed -r 's/(\[|\])//g'

Anda juga dapat mencoba pendekatan yang berbeda dan mencocokkan string di dalam tanda kurung (dengan asumsi string dapat dicocokkan dengan mudah dan tidak ditentukan oleh tanda kurung):

echo '[123]' | egrep -o "[0-9]+"

Saya mengalami masalah yang sama dengan regex asli Anda menggunakan grepjadi saya curiga ini bukan hanya sedhal.

Anehnya, ini menghasilkan hasil yang berbeda tetapi salah satunya cocok dengan yang Anda inginkan:

echo '[123]' | egrep -o '[^][]+'
123

echo '[123]' | egrep -o '[^[]]+'
3]

Menerapkan ini ke dokumen asli Anda sed(dan menambahkan /gpengubah sehingga menghapus kedua tanda kurung):

echo '[123]' | sed 's/[][]//g'
123
Ladadadada
sumber
Pendekatan ke-3 Anda (egrep -o ...) sepertinya solusi terbersih untuk masalah saya. Saya hanya akan memiliki bilangan bulat di antara tanda kurung siku (dan maaf, saya seharusnya menyebutkan itu dalam pertanyaan saya) jadi saya seharusnya tidak mengalami keanehan yang saya pikir. Terima kasih!
Xhantar
3
Anda juga dapat menggunakan tr: echo '[123]' | tr -d '[]'- menghindari kebingungan regexp tentang melarikan diri.
James O'Gorman
@ James O'Gorman - Menarik. Untuk beberapa alasan saya pikir itu trhanya dapat menerjemahkan satu karakter maks pada satu waktu, tetapi saya salah. Terima kasih!
Xhantar
4

Untuk menghapus semuanya sebelum dan sesudah tanda kurung:

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'
123

Jika data Anda seperti ini selalu berarti dimulai dan diakhiri dengan tanda kurung:

$ echo '[123]' | sed 's/.//;s/.$//;'
123
Guru
sumber
Data yang saya kerjakan akan selalu dimulai dan diakhiri dengan braket persegi ya. Saya masih ingin tahu mengapa solusi saya tidak berhasil. Ada ide? Dan apakah ada cara untuk melakukan ini tanpa menentukan 2x regex?
Xhantar
1
@Guru solusi ini bekerja dari saya, dan untuk Xhantar, Ini adalah jawaban yang sangat terlambat, tetapi apa yang dapat saya lihat dari kode Anda dan panduan Pemula Bash di tldp.org, Anda mencoba melakukan beberapa pencarian dan ganti, satu untuk '[' dan yang lain untuk ']' yang tidak akan berfungsi, untuk menghapus dua pencarian berbeda dan ganti gunakan ";" atau opsi -e. 's / <search> / <replace> / g; s / <search> / <replace> / g 'ATAU sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar
1

Jika Anda memiliki string yang lebih kompleks seperti 'abcdef [123] ghijk', Anda juga dapat menggunakan perintah bash internal 'cut' untuk mengekstrak teks hanya di antara tanda kurung:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123
valentt
sumber
1

Anda dapat menghindari braket pembuka menggunakan \[. Untuk braket penutup, gunakan []].

pengguna2428118
sumber