Hapus satu atau beberapa bidang, dibatasi oleh "-", di akhir baris

8

Saya akan mengurai data googleapis.txt

bucket,abc-def-ghi-45gjd4-wwxis
bucket,dde-wwq-ooi-66ciow-po22q
instance,jkl-mno-1-zzz-68dkakw-oo9w8
disk,pqr-stu-10-kuy-l2oxapw-rp4lt

Saya mengharapkan hasil seperti ini di bawah ini

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Saya berpikir bahwa saya harus berubah -menjadi spasi dan kemudian jalankan perintah ini

cat googleapis.txt | awk '{$NF="";sub(/[ \t]+$/,"")}1' | awk '{$NF="";sub(/[ \t]+$/,"")}1'

Saya mendapatkannya dari https://stackoverflow.com/a/27794421/8162936 Setelah diuraikan, saya akan mengubah ruang menjadi hipen -kembali.

Apakah ada yang tahu praktik terbaik atau perintah shell satu-liner untuk menguraikannya? Terima kasih semuanya

Nicky Puff
sumber

Jawaban:

10

dengan sedyang dapat Anda lakukan:

sed -E 's/(-[^-]*){2}$//' infile

cocokkan pola seperti -anythingdua kali (...){2}dari ujung $setiap baris dan hapus.

αғsнιη
sumber
7
$ sed 's/-[[:alnum:]]*-[[:alnum:]]*$//' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Ini digunakan seduntuk mencocokkan dua substring dasbor-dibatasi terakhir pada setiap baris dan menghapusnya. [[:alnum:]]akan cocok dengan karakter alfanumerik apa pun.

Anda dapat mempersingkat menjadi

sed 's/\(-[[:alnum:]]*\)\{2\}$//' file

yaitu, cocokkan dan hapus dua set -[[:alnum:]]*ath di akhir setiap baris.

Dengan GNU awk, Anda juga bisa melakukannya

$ awk -F '-' 'BEGIN { OFS=FS } { NF -= 2; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

tetapi mengubah NFseperti ini tidak portabel, dan harus dihindari (tidak ada jaminan bahwa itu mengubah catatan saat ini). Itu tidak akan bekerja dengan BSD awk, misalnya.

Dengan standar awk, tanpa menggunakan sub()(yang hanya akan meniru sed), Anda harus membuat ulang catatan saat ini dari bidang yang ingin Anda gunakan (dalam kasus kami, semua kecuali dua bidang batas-dasbor terakhir):

$ awk -F '-' 'BEGIN { OFS=FS } { nf = split($0,a) - 2; $0=""; for (i=1; i<=nf; ++i) $i = a[i]; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Kusalananda
sumber
4

Dengan revdan cut:

rev file | cut -d'-' -f3- | rev

Membalikkan garis, cutbidang 3 ke ujung baris dan membalikkan teks kembali.


Dengan grep(dan PCRE):

grep -Po '.*(?=(-[^-]*){2}$)' file
  • -Pgunakan ekspresi reguler yang kompatibel dengan perl dengan lookahead positif yang (?...)berisi dua kecocokan -diikuti oleh non- -karakter
  • -o hanya mencetak bagian yang cocok
Freddy
sumber
4
$ perl -F- -lane 'print join "-", @F[0..($#F-2)]' googleapis.txt
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Ini otomatis setiap baris input ke dalam array @F, menggunakan pembatas -.

Kemudian ia mencetak sepotong array kecuali dua bidang terakhir, digabung kembali dengan -karakter.

cas
sumber
1

Anda dapat melakukannya dengan berbagai cara seperti yang ditunjukkan di sini:

$ perl -F- -pale '$"="-";$#F-=2;$_="@F"' file

Pisahkan garis-garis pada tanda hubung, atur penggabung elemen array ke tanda hubung, klip dua elemen terakhir, dan atur garis saat ini ke array yang bergabung dengan tanda hubung.

$ awk -F- '{
   t = $1
   for ( i=2; i<NF-1; i++ ) t = t FS $i
   $0 = t
}1' file

Ini dengan pemrosesan string biasa:

$ perl -lne 'print substr($_, 0, rindex($_,"-",-1+rindex($_,"-")))' file

.

$ sed -ne '
   y/-/\n/
   :a;h;s/\n/-/;/\n.*\n/ba
   g;P
' file

Hasil:

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Rakesh Sharma
sumber