Jika Anda memiliki GNU grep, Anda dapat menggunakan -o
opsi untuk mencari regex dan hanya menghasilkan bagian yang cocok. (Implementasi grep lainnya hanya dapat menampilkan seluruh baris.) Jika ada beberapa kecocokan pada satu baris, mereka dicetak pada garis yang berbeda.
grep -o '\[[0-9]*\]'
Jika Anda hanya menginginkan angka dan bukan tanda kurung, itu sedikit lebih sulit; Anda perlu menggunakan pernyataan nol-lebar: regexp yang cocok dengan string kosong, tetapi hanya jika didahului, atau diikuti seperti kasusnya, dengan braket. Pernyataan nol-lebar hanya tersedia dalam sintaks Perl.
grep -P -o '(?<=\[)[0-9]*(?=\])'
Dengan sed, Anda harus mematikan pencetakan -n
, dan mencocokkan seluruh garis dan hanya mempertahankan bagian yang cocok. Jika ada beberapa kemungkinan kecocokan pada satu baris, hanya kecocokan terakhir yang dicetak. Lihat Mengekstrak regex yang cocok dengan 'sed' tanpa mencetak karakter di sekitarnya untuk detail lebih lanjut tentang penggunaan sed di sini.
sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'
atau jika Anda hanya menginginkan angka dan bukan tanda kurung:
sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'
Tanpa grep -o
, Perl adalah alat pilihan di sini jika Anda menginginkan sesuatu yang sederhana dan mudah dipahami. Di setiap baris ( -n
), jika baris berisi kecocokan untuk \[[0-9]*\]
, maka cetak kecocokan itu ( $&
) dan baris baru ( -l
).
perl -l -ne '/\[[0-9]*\]/ and print $&'
Jika Anda hanya menginginkan digit, letakkan tanda kurung di regex untuk membatasi grup, dan cetak hanya grup itu.
perl -l -ne '/\[([0-9]*)\]/ and print $1'
PS Jika Anda hanya ingin meminta satu angka atau lebih di antara tanda kurung, ubah [0-9]*
ke [0-9][0-9]*
, atau ke [0-9]+
dalam Perl.
[number]
" berarti kecuali[0-9]
perl
regex tersebut terlihat sangat berguna! Saya telah membaca tentang mereka setelah melihat Anda menggunakan pernyataan mundur dan maju, bahkan dalam grep (saya telah mematikan fakta Anda dapat memilih mesin regex). Saya akan mencurahkan sedikit lebih banyak waktu untuk perl's regex mulai dari sini. Terima kasih ... PS .. Saya baru saja membacaman grep
... "Ini sangat eksperimental dan grep -P dapat memperingatkan fitur yang tidak diimplementasikan." ... Saya harap itu tidak berarti tidak stabil (?) ...Anda tidak dapat melakukannya dengan
cut
.tr -c -d '0123456789\012'
sed 's/[^0-9]*//g'
awk -F'[^0-9]+' '{ print $1$2$3 }'
grep -o -E '[0-9]+'
tr
adalah solusi paling alami untuk masalah ini dan mungkin akan berjalan paling cepat, tetapi saya pikir Anda akan membutuhkan input raksasa untuk memisahkan salah satu opsi ini dalam hal kecepatan.sumber
^.*
apakah serakah dan mengkonsumsi semua kecuali digit terakhir, dan+
perlu\+
atau menggunakan posix\([0-9][0-9]*\)
.... dan dalam hal apapun's/[^0-9]*//g'
bekerja dengan baik,... Thanks for the
contoh tr -c`, tetapi bukankah itu trailing\012
surperfluous?\012
: diperlukan jika tidaktr
akan memakan baris baru.\0
,1
,2
(atau bahkan \, 0, 1, 2). Saya tidak cukup terbiasa dengan oktal sepertinya .. Terima kasih.Jika Anda bermaksud mengekstraksi serangkaian digit berturut-turut antara karakter non-digit, saya kira
sed
danawk
adalah yang terbaik (walaupungrep
juga dapat memberi Anda karakter yang cocok):sed
: Anda tentu saja dapat mencocokkan digit, tetapi mungkin menarik untuk melakukan yang sebaliknya, menghapus non-digit (berfungsi sejauh hanya ada satu angka per baris):grep
: Anda dapat mencocokkan digit berurutanSaya tidak memberikan contoh
awk
karena saya memiliki pengalaman nol dengannya; Sangat menarik untuk dicatat bahwa, meskipunsed
pisau swiss,grep
memberi Anda cara yang lebih sederhana dan lebih mudah dibaca untuk melakukan ini, yang juga berfungsi untuk lebih dari satu angka pada setiap jalur input (yang-o
hanya mencetak bagian yang cocok dari input, masing-masing pada jalurnya sendiri):sumber
sed
eqivalent dari "lebih dari satu nomor per baris" misalnyagrep -o '[[:digit:]]*'
. . .sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
... (+1)Karena telah dikatakan bahwa ini tidak dapat dilakukan dengan
cut
, saya akan menunjukkan bahwa adalah mudah untuk menghasilkan solusi yang setidaknya tidak lebih buruk daripada yang lain, meskipun saya tidak menganjurkan penggunaancut
sebagai "yang terbaik" (atau bahkan solusi yang sangat baik). Harus dikatakan bahwa solusi apa pun yang tidak mencari secara khusus untuk*[
dan di]*
sekitar digit membuat asumsi penyederhanaan dan karena itu rentan terhadap kegagalan pada contoh-contoh yang lebih kompleks daripada yang diberikan oleh penanya (misalnya angka di luar*[
dan]*
, yang tidak boleh ditampilkan). Solusi ini memeriksa setidaknya untuk tanda kurung, dan dapat diperluas untuk memeriksa tanda bintang juga (dibiarkan sebagai latihan untuk pembaca):Ini memanfaatkan
-d
opsi, yang menentukan pembatas. Jelas Anda juga bisa menyalurkan kecut
ekspresi daripada membaca dari file. Walaupuncut
mungkin cukup cepat, karena sederhana (tidak ada mesin regex), Anda harus memanggilnya setidaknya dua kali (atau beberapa waktu lagi untuk memeriksa*
), yang menciptakan beberapa proses overhead. Satu keuntungan nyata dari solusi ini adalah lebih mudah dibaca, terutama untuk pengguna biasa yang tidak berpengalaman dalam konstruksi regex.sumber