Xóa một hoặc nhiều trường, được phân định bởi một - -, ở cuối dòng


8

Tôi sẽ phân tích dữ liệu 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

Tôi mong đợi kết quả như thế này dưới đây

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

Tôi nghĩ rằng tôi phải thay đổi -để trở thành một không gian và sau đó chạy lệnh này

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

Tôi đã nhận được điều đó từ https://stackoverflow.com/a/27794421/8162936 Sau khi phân tích cú pháp, tôi sẽ thay đổi không gian để trở thành một hypen -trở lại.

Có ai biết thực hành tốt nhất hoặc lệnh shell-liner để phân tích nó không? Cảm ơn tất cả

Câu trả lời:


10

với sedbạn có thể làm:

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

nối một mẫu như -anythinghai lần (...){2}từ cuối $mỗi dòng và loại bỏ nó.


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

Điều này sử dụng sedđể khớp với hai chuỗi con được phân tách bằng dấu gạch ngang cuối cùng trên mỗi dòng và loại bỏ chúng. [[:alnum:]]sẽ phù hợp với bất kỳ ký tự chữ và số.

Bạn có thể rút ngắn nó xuống

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

tức là ghép và xóa hai bộ -[[:alnum:]]*ath ở cuối mỗi dòng.

Với GNU awk, bạn cũng có thể làm

$ 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

nhưng thay đổi NFnhư thế này không phải là di động và nên tránh (không có gì đảm bảo rằng nó thay đổi bản ghi hiện tại). Nó sẽ không hoạt động với BSD awk, ví dụ.

Với tiêu chuẩn awk, không dùng đến việc sử dụng sub()(sẽ chỉ bắt chước sed), bạn sẽ phải tạo lại bản ghi hiện tại từ các trường mà bạn muốn sử dụng (trong trường hợp của chúng tôi, trừ hai trường được phân tách bằng dấu gạch ngang cuối cùng):

$ 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

4

Với revcut:

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

Đảo ngược các dòng, cuttrường 3 đến cuối dòng và đảo ngược văn bản một lần nữa.


Với grep(và PCRE):

grep -Po '.*(?=(-[^-]*){2}$)' file
  • -Psử dụng các biểu thức chính quy tương thích perl với giao diện tích cực (?...)chứa hai kết quả khớp -theo sau bởi bất kỳ -ký tự không phải ký tự nào
  • -o chỉ in các phần phù hợp

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

Điều này tự động lấy từng dòng đầu vào thành mảng @F, sử dụng dấu phân cách -.

Sau đó, nó in một lát mảng của tất cả trừ hai trường cuối cùng, được nối lại với các -ký tự.


1

bạn có thể làm theo nhiều cách khác nhau như được hiển thị ở đây:

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

Tách các dòng trên một dấu gạch ngang, đặt công cụ nối phần tử mảng thành dấu gạch ngang, cắt hai phần tử cuối cùng và đặt dòng hiện tại thành mảng được nối với dấu gạch ngang.

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

Đây là với xử lý chuỗi đơn giản:

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

.

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

Các kết quả:

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.