Bài viết này là một phần của loạt bài Mẹo và thủ thuật Unix Sed đang được phát hành.
Trong các bài viết trước về sed, chúng ta đã học — in sed, xóa sed, thay thế sed, ghi tệp sed và nhiều lệnh sed.
Trong bài viết này, chúng ta hãy xem xét một số cách giải quyết thú vị bằng lệnh thay thế “s” trong sed bằng một số ví dụ thực tế.
Tôi. Dấu phân cách thay thế Sed
Như chúng ta đã thảo luận trong bài trước, chúng ta có thể sử dụng các dấu phân cách khác nhau, chẳng hạn như @ % |; :trong lệnh thay thế sed.
Trước tiên chúng ta hãy tạo tệp path.txt sẽ được sử dụng trong tất cả các ví dụ được đề cập bên dưới.
$ cat path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/omni/lbin:/opt/omni/sbin:/root/bin
Ví dụ 1 – sed@ dấu phân cách:Thay thế /opt/omni/lbin thành /opt/tools/bin
Khi bạn thay thế tên đường dẫn bằng '/', bạn có thể sử dụng @ làm dấu phân cách thay vì '/'. Trong ví dụ sed bên dưới, ở dòng cuối cùng của tệp đầu vào, /opt/omni/lbin đã được đổi thành /opt/tools/bin.
$ sed 's@/opt/omni/lbin@/opt/tools/bin@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/tools/bin:/opt/omni/sbin:/root/bin
Ví dụ 2 – sed / delimiter:Thay thế /opt/omni/lbin thành /opt/tools/bin
Khi bạn nên sử dụng '/' trong thay thế liên quan đến tên đường dẫn, bạn phải thoát '/' trong dữ liệu thay thế như hiển thị bên dưới. Trong ví dụ sed này, dấu phân cách '/' đã được thoát trong phần REGEXP và REPLACEMENT.
$ sed 's/\/opt\/omni\/lbin/\/opt\/tools\/bin/g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/tools/bin:/opt/omni/sbin:/root/bin
II. Sed ‘&’ Nhận chuỗi phù hợp
Phần chính xác của dòng đầu vào mà Biểu thức chính quy khớp với được biểu thị bằng &, sau đó có thể được sử dụng trong phần thay thế.
Ví dụ 1 – sed &Cách sử dụng:Thay thế /usr/bin/ thành /usr/bin/local
$ sed 's@/usr/bin@&/local@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin/local:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin/local:/opt/omni/bin: /opt/omni/lbin:/opt/omni/sbin:/root/bin
Trong ví dụ trên, '&' trong phần thay thế sẽ thay thế bằng /usr/bin mẫu phù hợp và thêm nó bằng /local. Vì vậy, ở đầu ra, tất cả sự xuất hiện của /usr/bin sẽ được thay thế bằng /usr/bin/local
Ví dụ 2 – sed &Cách sử dụng:Khớp toàn bộ dòng
&thay thế bất kỳ kết quả nào phù hợp bằng REGEXP đã cho.
$ sed 's@^.*$@<<<&>>>@g' path.txt <<</usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin>>> <<</usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:>>> <<</opt/omni/lbin:/opt/omni/sbin:/root/bin>>>
Trong ví dụ trên, biểu thức chính quy có “^.*$” khớp với toàn bộ dòng. Phần thay thế <<<&>>> ghi toàn bộ dòng với <<
III. Nhóm và tham chiếu ngược trong Sed
Việc nhóm có thể được sử dụng trong sed giống như biểu thức chính quy thông thường. Một nhóm được mở bằng “\(” và đóng bằng “\)”. Việc nhóm có thể được sử dụng kết hợp với tham chiếu ngược.
Tham chiếu ngược là việc sử dụng lại một phần của Biểu thức chính quy được chọn theo nhóm. Tham chiếu ngược trong sed có thể được sử dụng trong cả Biểu thức chính quy và phần thay thế của lệnh thay thế.
Ví dụ 1:Chỉ lấy đường dẫn đầu tiên trong mỗi dòng
$ sed 's/\(\/[^:]*\).*/\1/g' path.txt /usr/kbos/bin /usr/local/sbin /opt/omni/lbin
Trong ví dụ trên, \(\/[^:]*\) khớp với đường dẫn có sẵn trước :đầu tiên xuất hiện. \1 thay thế nhóm phù hợp đầu tiên.
Ví dụ 2:Đa nhóm
Trong file path.txt thay đổi thứ tự trường ở dòng cuối cùng của file.
$ sed '$s@\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\1@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/omni/bin: /root/bin:/opt/omni/sbin:/opt/omni/lbin
Trong lệnh trên $ chỉ định việc thay thế chỉ xảy ra ở dòng cuối cùng. Kết quả cho thấy thứ tự của các giá trị đường dẫn ở dòng cuối cùng đã bị đảo ngược.
Ví dụ 3:Lấy danh sách tên người dùng trong file /etc/passwd
Ví dụ sed này chỉ hiển thị trường đầu tiên từ tệp /etc/passwd.
$sed 's/\([^:]*\).*/\1/' /etc/passwd root bin daemon adm lp sync shutdown
Ví dụ 4:Đặt dấu ngoặc đơn cho ký tự đầu tiên của mỗi từ
Ví dụ sed này in ký tự đầu tiên của mỗi từ trong ngoặc đơn.
$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g' (W)elcome (T)o (T)he (G)eek (S)tuff
Ví dụ 5:Biên hòa số đơn.
Hãy để chúng tôi tạo tập tin có tên số có danh sách các số. Ví dụ về lệnh sed dưới đây được sử dụng để tính các số đến hàng nghìn.
$ cat numbers
1234
12121
3434
123
$sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers
1,234
12,121
3,434
123