Jadi saya punya garis:
ID: 54376
Bisakah Anda membantu saya membuat regex yang hanya akan mengembalikan nomor tanpa "ID:"?
CATATAN: String ini ada dalam file.
Jadi saya punya garis:
ID: 54376
Bisakah Anda membantu saya membuat regex yang hanya akan mengembalikan nomor tanpa "ID:"?
CATATAN: String ini ada dalam file.
Jawaban:
Coba ini:
grep -oP '(?<=ID: )[0-9]+' file
atau:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-odan -Padalah GNU ekstensi untuk grep. -obekerja di BSD juga. Dukungan PCRE -Ptidak selalu dikompilasi dengan baik.
Gunakan egrepdengan -oatau grepdengan -Eoopsi untuk mendapatkan hanya segmen yang cocok. Gunakan [0-9]sebagai regex untuk mendapatkan nomor saja:
grep -Eo [0-9]+ filename
Ada banyak cara untuk melakukan ini. Sebagai contoh:
Gunakan GNU grepdengan PCRE terbaru dan cocokkan angka setelah ID::
grep -oP 'ID:\s*\K\d+' file
Gunakan awkdan cukup cetak bidang terakhir dari semua baris yang dimulai denganID:
awk '/^ID:/{print $NF}' file
Itu juga akan mencetak bidang yang bukan angka, untuk mendapatkan angka saja, dan hanya di bidang kedua, gunakan
awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
Gunakan GNU grep dengan Ekspresi Reguler Diperpanjang dan parsing dua kali:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\Kyang dilakukan dalam contoh pertama?
-ountuk mencetak hanya bagian yang cocok tetapi juga membuang hal-hal yang saya tidak tertarik. Bandingkan echo "foobar" | grep -oP "foobar"danecho "foobar" | grep -oP 'foo\Kbar'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Itu hanya akan mencetak semua angka dan spasi yang terjadi setelah ID: 54376input file apa pun.
Saya baru saja memperbarui sedikit di atas untuk membuatnya sedikit lebih cepat dengan *dan tidak pmerusak garis kosong setelah menghapus karakter non-{numeric, spasi}.
Ini alamat baris dari regex /ID: 54376/ ,melalui yang $terakhir dan pada mereka s///menghapus semua atau *karakter apa pun ^tidak [^ 0-9]*kemudian pmerusak /setiap /baris dengan .karakter yang tersisa.
{
echo line
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
Menggunakan sed:
{
echo "ID: 1"
echo "Line doesn't start with ID: "
echo "ID: Non-numbers"
echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'
Ini -nadalah "jangan cetak apa pun secara default", /^ID: [0-9][0-9]*$/adalah "untuk baris yang cocok dengan regex ini" (dimulai dengan "ID:", lalu 1 digit atau lebih, lalu ujung baris), dan s/ID: //pisian formulir s/pattern/repl/flags- sartinya kita sedang melakukan pengganti, untuk mengganti pola "ID: "dengan teks pengganti ""(string kosong) menggunakan pbendera, yang berarti "cetak baris ini setelah melakukan penggantian".
Keluaran:
1
4
Perintah sed GNU lain,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Ini mencetak nomor apa pun setelah ID:
+. Jika perbedaan antara satu karakter dan 3 karakter adalah naskah Anda mungkin tidak bekerja di semua seds Anda mungkin harus melakukan: sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'. Jawaban Anda juga meleset ID: [0-9]pada baris pertama yang berisi dua kejadian ID: [0-9].
Gunakan grep + awk:
grep "^ID" your_file | awk {'print $2'}
Bonus: mudah dibaca :)
grepjika menggunakan awk. awk '/^ID/ { print $2 }'melakukan hal yang sama, dan menghindari masalah line-buffering grep . Ini juga hampir sama dengan salah satu solusi dalam jawaban @ terdon.