Thứ ba, 19/05/2020 | 00:00 GMT+7

Sedan trung gian: Thao tác các dòng văn bản trong môi trường Linux

Editor stream sed là một công cụ chỉnh sửa mạnh mẽ có thể áp dụng các thay đổi sâu rộng với rất ít đầu vào. Trong bài viết trước về sed , bạn đã tìm hiểu những kiến thức cơ bản về việc sử dụng sed để soạn thảo văn bản .

Bài viết này sẽ tiếp tục phần giới thiệu của bạn bằng cách kiểm tra một số chủ đề nâng cao hơn.

Lưu ý : Hướng dẫn này sử dụng version GNU của sed được tìm thấy trên Ubuntu và các hệ điều hành Linux khác. Nếu bạn đang sử dụng macOS, bạn sẽ có version BSD có các tùy chọn và đối số khác nhau. Bạn có thể cài đặt version GNU của sed với Homebrew bằng cách sử dụng brew install gnu-sed .

Để hoàn thành hướng dẫn này, bạn cần một số file để thao tác, mà bạn nên có từ hướng dẫn đầu tiên. Nếu bạn không có chúng, bạn có thể tạo lại chúng bằng các lệnh sau:

  • cd
  • cp /usr/share/common-licenses/BSD .
  • echo "this is the song that never ends
  • yes, it goes on and on, my friend
  • some people started singing it
  • not knowing what it was
  • and they'll continue singing it forever
  • just because..." > song.txt

Ngoài ra, bạn sẽ sử dụng giấy phép GPL 3 trong hướng dẫn này, vì vậy hãy sao chép file đó:

  • cp /usr/share/common-licenses/GPL-3 .

Nếu bạn không có nó, bạn có thể download với curl :

  • curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

Đến đây bạn đã có các file , bạn sẽ khám phá bằng cách sử dụng sed với nhiều lệnh.

Cung cấp nhiều trình tự chỉnh sửa

Có khá nhiều trường hợp mà bạn có thể cần chuyển nhiều lệnh đến sed đồng thời. Có một số cách để thực hiện điều này.

sed hoạt động thông qua đầu vào và kết quả tiêu chuẩn, bạn có thể xâu chuỗi các lệnh gọi khác nhau đến sed với nhau thông qua một đường ống. Thực thi lệnh này để thay thế từ and bằng dấu chấm & ( & ) và từ peoplehorses :

  • sed 's/and/\&/' song.txt | sed 's/people/horses/'

Lưu ý bạn cần phải thoát khỏi “&” vì nó nghĩa là “mẫu phù hợp hoàn chỉnh” thành sed ):

Bạn sẽ thấy kết quả sau:

Output
this is the song that never ends yes, it goes on & on, my friend some horses started singing it not knowing what it was & they'll continue singing it forever just because...

Điều này hoạt động, nhưng nó tạo ra chi phí không cần thiết với nhiều cuộc gọi đến sed , yêu cầu nhập nhiều hơn và không tận dụng được các khả năng tích hợp của sed .

Bạn có thể xâu chuỗi các lệnh khác nhau thành sed bằng cách sử dụng tùy chọn -e trước mỗi lệnh. Đây là cách bạn viết lại lệnh trước đó:

  • sed -e 's/and/\&/' -e 's/people/horses/' song.txt

Một cách tiếp cận khác để xâu chuỗi các lệnh lại với nhau là sử dụng ký tự dấu chấm phẩy ( ; ) để phân tách các lệnh riêng biệt. Điều này hoạt động giống như ví dụ trước, nhưng " -e " không bắt buộc:

  • sed 's/and/\&/;s/people/horses/' song.txt

Lưu ý khi sử dụng cấu trúc -e , bạn cần các group dấu ngoặc kép riêng biệt cho các lệnh khác nhau. Tuy nhiên, khi phân tách các lệnh bằng dấu chấm phẩy, tất cả các lệnh chỉ được đặt trong một chuỗi lệnh được trích dẫn đơn. Mặc dù hai cách thể hiện nhiều lệnh này rất hữu ích, nhưng đôi khi kỹ thuật đặt đường ống trước đó vẫn được yêu cầu.

Hãy xem xét toán tử = . Toán tử này chèn một số dòng trên một dòng mới giữa mỗi dòng hiện có. Đầu ra trông như thế này:

  • sed '=' song.txt

Đây là kết quả bạn sẽ thấy:

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it 4 not knowing what it was 5 and they'll continue singing it forever 6 just because...

Tuy nhiên, nếu bạn muốn thay đổi định dạng của số bằng cách sửa đổi văn bản, bạn sẽ thấy rằng mọi thứ không hoạt động như mong đợi.

Để chứng minh, hãy xem lệnh G , theo mặc định, nhập một dòng trống giữa mỗi dòng (điều này thực sự phức tạp hơn, nhưng bạn sẽ khám phá điều đó sau):

  • sed 'G' song.txt

Đây là kết quả:

Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because...

Nếu bạn kết hợp hai lệnh này, bạn có thể mong đợi khoảng cách giữa mỗi lệnh
dòng thông thường và dòng số-dòng:

  • sed '=;G' song.txt

Tuy nhiên, bạn nhận được một cái gì đó khác nhau:

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it 4 not knowing what it was . . . . . .

Điều này xảy ra bởi vì toán tử = sửa đổi trực tiếp stream kết quả thực tế. Điều này nghĩa là bạn không thể sử dụng kết quả để chỉnh sửa thêm.

Bạn có thể giải quyết vấn đề này bằng cách sử dụng hai lệnh gọi sed , coi sửa đổi sed đầu tiên như một dòng văn bản đơn giản cho lần thứ hai:

  • sed '=' song.txt | sed 'G'

Đến đây bạn thấy kết quả mà bạn mong đợi:

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it . . . . . .

Lưu ý một số lệnh hoạt động như vậy, đặc biệt nếu bạn đang xâu chuỗi nhiều lệnh với nhau và kết quả kết quả khác với những gì bạn mong đợi.

Địa chỉ nâng cao

Một trong những lợi thế của các lệnh địa chỉ của sed là các biểu thức chính quy được dùng làm tiêu chí lựa chọn. Điều này nghĩa là bạn không bị giới hạn hoạt động trên các giá trị dòng đã biết, như bạn đã thấy trước đây:

  • sed '1,3s/.*/Hello/' song.txt
Output
Hello Hello Hello not knowing what it was and they'll continue singing it forever just because...

Thay vào đó, bạn có thể sử dụng biểu thức chính quy để chỉ trùng với các dòng có chứa một mẫu nhất định. Để thực hiện việc này, hãy đặt mẫu khớp giữa hai dấu gạch chéo về phía trước (/) trước khi đưa ra các chuỗi lệnh:

  • sed '/singing/s/it/& loudly/' song.txt
Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it loudly not knowing what it was and they'll continue singing it loudly forever just because...

Trong ví dụ này, bạn đã đặt loudly sau lần xuất hiện đầu tiên của it trên mỗi dòng có chứa chuỗi singing . Lưu ý dòng thứ hai và thứ tư không thay đổi vì chúng không trùng với mẫu.

Các biểu thức cho địa chỉ có thể phức tạp tùy ý. Điều này cung cấp rất nhiều tính linh hoạt trong việc thực hiện các lệnh.

Đây không phải là một ví dụ phức tạp, nhưng nó thể hiện việc sử dụng các biểu thức chính quy để tạo địa chỉ cho các lệnh khác. Lệnh sau đây trùng với bất kỳ dòng trống nào (đầu dòng theo sau ngay cuối dòng) và chuyển chúng đến lệnh xóa:

  • sed '/^$/d' GPL-3

Đây là kết quả bạn sẽ thấy:

Output
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for . . . . . .

Lưu ý bạn cũng có thể sử dụng biểu thức chính quy ở cả hai bên của một phạm vi. Ví dụ: bạn có thể xóa các dòng bắt đầu từ dòng chỉ chứa từ START cho đến khi dòng đọc END ,

Ví dụ: tạo một file có tên là inputfile :

  • echo "This is an input file
  • START
  • this is the text we don't want
  • END
  • This is additional text" > inputfile

Bây giờ sử dụng sed để xóa nội dung giữa STARTEND :

  • sed '/^START$/,/^END$/d' inputfile

Bạn sẽ thấy kết quả sau:

This is an input file This is additional text 

Tuy nhiên, cần lưu ý một điều là thao tác này sẽ xóa mọi thứ từ START đầu tiên đến END đầu tiên và sau đó bắt đầu lại quá trình xóa nếu nó gặp phải một điểm đánh dấu START khác.

Nếu bạn muốn đảo một địa chỉ (thao tác trên bất kỳ dòng nào không trùng với một mẫu), bạn có thể làm theo mẫu với dấu chấm than ( ! ).

Ví dụ: bạn có thể xóa bất kỳ dòng nào không trống (không hữu ích lắm, nhưng chỉ là một ví dụ), bằng lệnh sau:

  • sed '/^$/!d' GPL-3

Điều này dẫn đến kết quả trống lớn, vì sed vẫn in các dòng theo mặc định:

Output

Địa chỉ không cần phải là một biểu thức phức tạp để được đảo ngược. Đảo ngược cũng hoạt động tương tự trên địa chỉ được đánh số thông thường.

Sử dụng đệm giữ

Một phần của chức năng làm tăng khả năng của sed thực hiện các chỉnh sửa nhận biết nhiều dòng là cái được gọi là “ cache giữ”. Cache lưu giữ là một vùng lưu trữ tạm thời có thể được sửa đổi bằng các lệnh nhất định.

Sự hiện diện của cache bổ sung này nghĩa là bạn có thể lưu trữ các dòng trong khi làm việc trên các dòng khác, sau đó hoạt động trên từng cache khi cần thiết.

Sau đây là các lệnh ảnh hưởng đến cache giữ:

  • h : Sao chép cache mẫu hiện tại (dòng bạn hiện đang khớp và đang làm việc) vào cache giữ (điều này sẽ xóa nội dung trước đó của cache giữ).
  • H : Thêm cache mẫu hiện tại vào cuối mẫu đang giữ hiện tại, được phân tách bằng ký tự dòng mới (\ n).
  • g : Sao chép cache đang giữ hiện tại vào cache mẫu hiện tại. Cache mẫu trước đó sẽ bị xóa.
  • G : Thêm mẫu đang giữ hiện tại vào cuối cache mẫu hiện tại, được phân tách bằng ký tự dòng mới (\ n).
  • x : Swap mẫu hiện tại và giữ cache .

Không thể sử dụng nội dung của cache giữ cho đến khi nó được chuyển đến cache mẫu theo cách này hay cách khác.

Hãy cùng khám phá ý tưởng này với một ví dụ phức tạp.

Đây là một ví dụ thủ tục về cách nối các dòng liền kề ( sed thực sự có một lệnh tích hợp sẽ xử lý rất nhiều việc này cho ta . Lệnh N nối dòng tiếp theo vào dòng hiện tại. Bạn sẽ thực hiện những việc con đường khó mặc dù vì lợi ích của việc thực hành):

  • sed -n '1~2h;2~2{H;g;s/\n/ /;p}' song.txt

Đây là kết quả bạn sẽ thấy:

Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because...

Điều này là rất nhiều để tiêu hóa, vì vậy hãy chia nhỏ nó.

Điều đầu tiên cần lưu ý là tùy chọn -n được sử dụng để ngăn chế độ in tự động. sed sẽ chỉ in khi bạn nói cụ thể.

Phần đầu tiên của hướng dẫn là 1\~2h . Bắt đầu là một đặc tả địa chỉ nghĩa là thực hiện thao tác tiếp theo trên dòng đầu tiên, và sau đó trên mọi dòng khác sau đó (mỗi dòng được đánh số lẻ). Phần h là lệnh sao chép dòng đã khớp vào cache giữ.

Nửa sau của lệnh phức tạp hơn. , nó bắt đầu với một đặc tả địa chỉ. Lần này, nó đề cập đến các dòng được đánh số chẵn (ngược lại với lệnh đầu tiên).

Phần còn lại của lệnh được đặt trong dấu ngoặc nhọn. Điều này nghĩa là phần còn lại của các lệnh sẽ kế thừa địa chỉ vừa được chỉ định. Không có dấu ngoặc nhọn, chỉ lệnh “H” sẽ kế thừa địa chỉ và phần còn lại của các lệnh sẽ được thực hiện trên mọi dòng.

Lệnh H sao chép một ký tự dòng mới, theo sau là cache mẫu hiện tại, vào cuối mẫu đang giữ hiện tại.

Mẫu giữ này (một dòng được đánh số lẻ, theo sau là một ký tự dòng mới, tiếp theo là một dòng số chẵn) sau đó được sao chép trở lại vào cache mẫu (thay thế cache mẫu trước đó) bằng lệnh g .

Tiếp theo, ký tự dòng mới được thay thế bằng khoảng trắng và dòng được in bằng lệnh p .

Nếu bạn tò mò, sử dụng lệnh N sẽ rút ngắn điều này đáng kể. Lệnh sau sẽ tạo ra kết quả tương tự như bạn vừa thấy:

  • sed -n 'N;s/\n/ /p' song.txt

Sử dụng tập lệnh

Khi bạn bắt đầu sử dụng các lệnh phức tạp hơn, có thể hữu ích khi soạn chúng trong editor . Điều này cũng hữu ích nếu bạn có một số lượng lớn lệnh mà bạn muốn áp dụng cho một mục tiêu duy nhất.

Ví dụ: nếu bạn muốn soạn thư ở dạng văn bản thuần túy, nhưng bạn cần thực hiện một tập hợp các định dạng chuẩn trước khi sử dụng văn bản, thì một tập lệnh sed sẽ hữu ích.

Thay vì nhập từng group lệnh gọi sed , bạn có thể đặt các lệnh trong một tập lệnh và cung cấp nó làm đối số cho sed . Tập lệnh sed chỉ đơn giản là một danh sách các lệnh sed thô (phần thường nằm giữa các ký tự dấu nháy đơn).

Để thử điều này, hãy tạo một file mới có tên sed_script với nội dung sau:

  • echo "s/this/that/g
  • s/people/horses/g
  • 1,5s/it/that/g" > sed_script

Lưu file và thoát khỏi editor .

Bây giờ yêu cầu sed sử dụng file bằng cách sử dụng chuyển đổi -f :

  • sed -f sed_script song.txt

Kết quả sẽ như thế này:

Output
that is the song that never ends yes, that goes on and on, my friend some horses started singing that not knowing what that was and they'll continue singing that forever just because...

Điều này cho phép bạn đặt tất cả các chỉnh sửa của bạn trong một file và thực thi nó trên các file văn bản tùy ý cần tuân theo định dạng bạn đã tạo.

Kết luận

Lúc đầu, các lệnh của Sed không phải lúc nào cũng dễ hiểu và thường phải trải qua một số thử nghiệm thực tế để có được ý tưởng về tiện ích của chúng. Vì lý do này, bạn nên thực hành thao tác văn bản trước khi thực sự cần. Có mục tiêu cuối cùng trong đầu và cố gắng thực hiện nó chỉ bằng cách sử dụng sed .

Hy vọng rằng đến thời điểm này, bạn đã bắt đầu hiểu được sức mạnh mà việc thành thạo sed đúng cách có thể mang lại cho bạn. Bạn càng thoải mái với sed , bạn sẽ càng ít phải làm việc về lâu dài.


Tags:

Các tin liên quan

Khái niệm cơ bản về việc sử dụng Sed Stream Editor để thao tác văn bản trong Linux
2020-05-19
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Ubuntu 20.04 [Quickstart]
2020-05-14
Cách thiết lập Nền tảng Cloud IDE server mã trên Ubuntu 18.04
2020-05-13
Cách tạo server Minecraft trên Ubuntu 18.04
2020-05-07
Cách tạo server Minecraft trên Ubuntu 20.04
2020-05-07
Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Ubuntu 20.04 [Quickstart]
2020-05-07
Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Ubuntu 20.04
2020-04-29
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Ubuntu 20.04
2020-04-29
Thiết lập bảo mật server quan trọng với Ubuntu 20.04
2020-04-23
Cách cài đặt Linux, Nginx, MySQL, PHP (LEMP) trên CentOS 7
2020-04-21