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

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

Lệnh sed , viết tắt của trình chỉnh sửa luồng , thực hiện các thao tác chỉnh sửa trên văn bản đến từ đầu vào chuẩn hoặc một file . sed chỉnh sửa từng dòng một và theo cách không tương tác.

Điều này nghĩa là bạn thực hiện tất cả các quyết định chỉnh sửa khi bạn đang gọi lệnh và sed thực hiện các hướng dẫn tự động. Điều này có vẻ khó hiểu hoặc không trực quan, nhưng nó là một cách rất mạnh mẽ và nhanh chóng để chuyển đổi văn bản, đặc biệt là một phần của tập lệnh hoặc quy trình làm việc tự động.

Hướng dẫn này sẽ trình bày một số thao tác cơ bản và giới thiệu cho bạn cú pháp cần thiết để vận hành trình soạn thảo này. Bạn gần như chắc chắn sẽ không bao giờ thay thế editor thông thường của bạn bằng sed , nhưng nó có thể sẽ trở thành một bổ sung đáng hoan nghênh cho hộp công cụ soạn thảo văn bản của bạ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 .

Cách sử dụng cơ bản

sed hoạt động trên một stream văn bản mà nó đọc từ file văn bản hoặc từ đầu vào chuẩn (STDIN). Điều này nghĩa là bạn có thể gửi trực tiếp kết quả của một lệnh khác vào sed để chỉnh sửa hoặc bạn có thể làm việc trên file mà bạn đã tạo.

Bạn cũng nên biết rằng sed xuất mọi thứ thành tiêu chuẩn (STDOUT) theo mặc định. Điều đó nghĩa là , trừ khi được chuyển hướng, sed sẽ in kết quả của nó ra màn hình thay vì lưu nó trong một file .

Cách sử dụng cơ bản là:

  • sed [options] commands [file-to-edit]

Trong hướng dẫn này, bạn sẽ sử dụng bản sao Giấy phép Phần mềm BSD để thử nghiệm với sed . Trên Ubuntu, thực hiện các lệnh sau để sao chép file giấy phép BSD vào folder chính của bạn để bạn có thể làm việc với nó:

  • cd
  • cp /usr/share/common-licenses/BSD .

Nếu bạn không có bản sao local của giấy phép BSD, hãy tự tạo một bản sao bằng lệnh sau:

  • cat << 'EOF' > BSD
  • Copyright (c) The Regents of the University of California.
  • All rights reserved.
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions
  • are met:
  • 1. Redistributions of source code must retain the above copyright
  • notice, this list of conditions and the following disclaimer.
  • 2. Redistributions in binary form must reproduce the above copyright
  • notice, this list of conditions and the following disclaimer in the
  • documentation and/or other materials provided with the distribution.
  • 3. Neither the name of the University nor the names of its contributors
  • may be used to endorse or promote products derived from this software
  • without specific prior written permission.
  • THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  • ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  • IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  • ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  • FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  • DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  • OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  • HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  • LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  • OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  • SUCH DAMAGE.
  • EOF

Hãy sử dụng sed để xem nội dung của file giấy phép BSD. sed gửi kết quả của nó đến màn hình theo mặc định, nghĩa là bạn có thể sử dụng nó như một trình đọc file bằng cách chuyển nó mà không cần lệnh chỉnh sửa. Hãy thử thực hiện lệnh sau:

  • sed '' BSD

Bạn sẽ thấy giấy phép BSD được hiển thị trên màn hình:

Output
Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ... ...

Các dấu nháy đơn chứa các lệnh chỉnh sửa mà bạn chuyển cho sed . Trong trường hợp này, bạn không vượt qua nó, vì vậy sed in từng dòng nó nhận được thành kết quả tiêu chuẩn.

sed có thể sử dụng đầu vào tiêu chuẩn hơn là một file . Đưa kết quả của lệnh cat vào sed để tạo ra kết quả tương tự:

  • cat BSD | sed ''

Bạn sẽ thấy kết quả của file :

Output
Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . . . . . .

Như bạn thấy , bạn có thể thao tác trên các file hoặc stream văn bản, giống như các file hoặc stream văn bản được tạo ra khi xuất kết quả bằng ký tự pipe (|) , dễ dàng như vậy.

Dòng in

Trong ví dụ trước, bạn đã thấy rằng đầu vào được truyền vào sed mà không có bất kỳ thao tác nào sẽ in kết quả trực tiếp ra kết quả chuẩn.

Hãy khám phá lệnh print rõ ràng của sed , mà bạn chỉ định bằng cách sử dụng ký tự p trong các dấu nháy đơn.

Thực hiện lệnh sau:

  • sed 'p' BSD

Bạn sẽ thấy mỗi dòng của file BSD được in hai lần:

Output
Copyright (c) The Regents of the University of California. Copyright (c) The Regents of the University of California. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions are met: are met: . . . . . .

sed tự động in từng dòng theo mặc định và sau đó bạn đã yêu cầu nó in các dòng một cách rõ ràng bằng lệnh “p”, vì vậy bạn sẽ in mỗi dòng hai lần.

Nếu bạn kiểm tra kỹ kết quả , bạn sẽ thấy rằng nó có dòng đầu tiên hai lần, tiếp theo là dòng thứ hai hai lần, v.v., điều này cho bạn biết rằng sed hoạt động trên từng dòng dữ liệu. Nó đọc một dòng, thao tác trên đó và xuất ra văn bản kết quả trước khi lặp lại quy trình trên dòng tiếp theo.

Bạn có thể xóa kết quả bằng cách chuyển tùy chọn -n cho sed , tùy chọn này sẽ ngăn chế độ in tự động:

  • sed -n 'p' BSD
Output
Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . . . . . .

Bây giờ ta quay lại in từng dòng một lần.

Các ví dụ cho đến nay khó có thể được coi là chỉnh sửa (trừ khi bạn muốn in mỗi dòng hai lần…). Tiếp theo, bạn sẽ khám phá cách sed có thể sửa đổi kết quả bằng cách nhắm đến các phần cụ thể của dữ liệu văn bản.

Sử dụng Dải địa chỉ

Địa chỉ cho phép bạn nhắm đến các phần cụ thể của stream văn bản. Bạn có thể chỉ định một dòng cụ thể hoặc thậm chí một loạt các dòng.

Hãy để sed in dòng đầu tiên của file . Thực hiện lệnh sau:

  • sed -n '1p' BSD

Dòng đầu tiên in ra màn hình:

Output
Copyright (c) The Regents of the University of California.

Bằng cách đặt số 1 trước lệnh in, bạn đã cho sed số dòng hoạt động. Bạn có thể dễ dàng in năm dòng (đừng quên “-n”):

  • sed -n '1,5p' BSD

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

Output
Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions

Bạn vừa cung cấp một dải địa chỉ cho sed . Nếu bạn cung cấp địa chỉ cho sed , nó sẽ chỉ thực hiện các lệnh tiếp theo trên các dòng đó. Trong ví dụ này, bạn đã yêu cầu sed in từ dòng 1 đến dòng 5. Bạn có thể chỉ định điều này theo một cách khác bằng cách đưa ra địa chỉ đầu tiên và sau đó sử dụng một khoảng cách để cho sed có bao nhiêu dòng bổ sung để di chuyển, như thế này:

  • sed -n '1,+4p' BSD

Điều này sẽ dẫn đến cùng một kết quả , vì bạn đã yêu cầu sed bắt đầu ở dòng 1 và sau đó hoạt động trên 4 dòng tiếp theo.

Nếu bạn muốn in mọi dòng khác, hãy chỉ định khoảng sau ký tự ~ . Lệnh sau sẽ in mọi dòng khác trong file BSD , bắt đầu bằng dòng 1:

  • sed -n '1~2p' BSD

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

Output
Copyright (c) The Regents of the University of California. modification, are permitted provided that the following conditions 1. Redistributions of source code must retain the above copyright 2. Redistributions in binary form must reproduce the above copyright documentation and/or other materials provided with the distribution. may be used to endorse or promote products derived from this software . . . . . .

Bạn cũng có thể sử dụng sed để xóa văn bản khỏi kết quả .

Xóa văn bản

Bạn có thể thực hiện xóa văn bản mà trước đó bạn đã chỉ định in văn bản bằng cách thay đổi lệnh p lệnh d .

Trong trường hợp này, bạn không cần lệnh -nsed sẽ in mọi thứ không bị xóa. Điều này sẽ giúp bạn thấy những gì đang xảy ra.

Sửa đổi lệnh cuối cùng từ phần trước để làm cho nó
xóa mọi dòng khác bắt đầu bằng dòng đầu tiên:

  • sed '1~2d' BSD

Kết quả là bạn thấy mọi dòng bạn không được cung cấp lần trước:

Output
All rights reserved. Redistribution and use in source and binary forms, with or without are met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the 3. Neither the name of the University nor the names of its contributors without specific prior written permission. . . . . . .

Điều quan trọng cần lưu ý ở đây là file nguồn của ta không bị ảnh hưởng. Nó vẫn còn nguyên vẹn. Các chỉnh sửa được xuất ra màn hình của ta .

Nếu ta muốn lưu các chỉnh sửa của bạn , ta có thể chuyển hướng kết quả tiêu chuẩn đến một file như sau:

  • sed '1~2d' BSD > everyother.txt

Bây giờ hãy mở file bằng cat :

  • cat everyother.txt

Bạn thấy kết quả tương tự mà bạn đã thấy trên màn hình trước đây:

Output
All rights reserved. Redistribution and use in source and binary forms, with or without are met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the 3. Neither the name of the University nor the names of its contributors without specific prior written permission. . . . . . .

Lệnh sed không chỉnh sửa file nguồn theo mặc định, nhưng bạn có thể thay đổi hành vi này bằng cách chuyển tùy chọn -i , nghĩa là “thực hiện chỉnh sửa tại chỗ”. Điều này sẽ làm thay đổi file nguồn.

Cảnh báo : Sử dụng lựa chọn -i sẽ overrides lên file root , vì vậy bạn nên cẩn thận khi sử dụng. Trước tiên, hãy thực hiện các thao tác mà không cần chuyển đổi -i , sau đó chạy lại lệnh với -i khi bạn đã có những gì mình muốn, tạo bản backup của file root hoặc chuyển hướng kết quả thành file . Rất dễ vô tình làm thay đổi file root bằng lựa chọn -i .

Hãy thử nó bằng cách chỉnh sửa file everyother.txt bạn vừa tạo tại chỗ. Hãy giảm file hơn nữa bằng cách xóa mọi dòng khác
lần nữa:

  • sed -i '1~2d' everyother.txt

Nếu bạn sử dụng cat để hiển thị file với cat everyother.txt , bạn sẽ thấy rằng file đã được chỉnh sửa.

Tùy chọn -i có thể nguy hiểm . Rất may, sed cung cấp cho bạn khả năng tạo file backup trước khi chỉnh sửa.

Để tạo file backup trước khi chỉnh sửa, hãy thêm tiện ích mở rộng backup trực tiếp sau tùy chọn “-i”:

  • sed -i.bak '1~2d' everyother.txt

Thao tác này tạo file backup có phần mở rộng .bak , sau đó chỉnh sửa file root tại chỗ.

Tiếp theo, bạn sẽ xem xét cách sử dụng sed để thực hiện các thao tác tìm kiếm và thay thế.

Văn bản thay thế

Có lẽ cách sử dụng nổi tiếng nhất cho sed là thay thế văn bản. sed có thể tìm kiếm các mẫu văn bản bằng cách sử dụng cụm từ thông dụng, sau đó thay thế văn bản tìm được bằng một thứ khác.

Bạn có thể tìm hiểu thêm về biểu thức chính quy theo Sử dụng biểu thức chính quy Grep để tìm kiếm mẫu văn bản trong Linux .

Ở dạng cơ bản nhất, bạn có thể thay đổi từ này sang từ khác bằng cú pháp sau:

's/old_word/new_word/' 

s là lệnh thay thế. Ba dấu gạch chéo ( / ) được sử dụng để phân tách các trường văn bản khác nhau. Bạn có thể sử dụng các ký tự khác để phân cách các trường nếu nó hữu ích hơn.

Ví dụ: nếu bạn đang cố gắng thay đổi tên trang web, sử dụng dấu phân tách khác sẽ hữu ích vì URL chứa dấu gạch chéo.

Thực thi lệnh sau để in một URL với echo và sửa đổi nó bằng sed , sử dụng ký tự gạch dưới ( _ ) làm dấu phân cách:

  • echo "http://www.example.com/index.html" | sed 's_com/index_org/home_'

Điều này thay thế com/index bằng org/home . Đầu ra hiển thị URL đã sửa đổi:

Output
http://www.example.org/home.html

Đừng quên dấu phân cách cuối cùng, nếu không sed sẽ phàn nàn. Nếu bạn chạy lệnh này:

  • echo "http://www.example.com/index.html" | sed 's_com/index_org/home'

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

Output
sed: -e expression #1, char 20: unterminated `s' command

Hãy tạo một file mới để thực hành một số thay thế. Thực hiện lệnh sau để tạo một file văn bản mới có tên là song.txt :

  • 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

Bây giờ hãy thay thế biểu thức on bằng forward . Sử dụng lệnh sau:

  • sed 's/on/forward/' song.txt

Đầu ra trông như thế này:

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

Bạn có thể thấy một vài điều đáng chú ý ở đây. Đầu tiên, đó là mẫu thay thế sed , không phải từ. song on trong được chuyển thành forward .

Điều khác để thông báo là trên dòng 2, thứ hai on đã không được thay đổi để forward .

Điều này là do theo mặc định, lệnh s hoạt động trên khớp đầu tiên trong một dòng và sau đó chuyển sang dòng tiếp theo. Để làm cho sed thay thế mọi version của on thay vì chỉ version đầu tiên trên mỗi dòng, bạn phải chuyển một cờ tùy chọn cho lệnh thay thế.

Cung cấp cờ g cho lệnh thay thế bằng cách đặt nó sau bộ thay thế:

  • sed 's/on/forward/g' song.txt

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

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

Bây giờ lệnh thay thế thay đổi mọi trường hợp.

Nếu bạn chỉ muốn thay đổi version thứ hai của “on” mà sed tìm thấy trên mỗi dòng, thì bạn sẽ sử dụng số 2 thay vì g :

  • sed 's/on/forward/2' song.txt

Lần này các dòng khác không thay đổi, vì chúng không có lần xuất hiện thứ hai:

Output
this is the song that never ends yes, it goes on and forward, 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 chỉ muốn xem dòng nào đã được thay thế, hãy sử dụng lại tùy chọn -n để tắt tính năng in tự động.

Sau đó, bạn có thể chuyển tùy chọn p cho lệnh thay thế để in các dòng nơi quá trình thay thế diễn ra.

  • sed -n 's/on/forward/2p' song.txt

Dòng đã thay đổi bản in ra màn hình:

Output
yes, it goes on and forward, my friend

Như bạn thấy, bạn có thể kết hợp các cờ ở cuối lệnh.

Nếu bạn muốn quá trình tìm kiếm bỏ qua chữ hoa chữ thường, bạn có thể chuyển cho nó cờ “i”.

  • sed 's/SINGING/saying/i' 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 saying it not knowing what it was and they'll continue saying it forever just because...

Thay thế và Tham chiếu Văn bản Phù hợp

Nếu bạn muốn tìm các mẫu phức tạp hơn với các biểu thức chính quy, bạn có một số phương pháp khác nhau để tham chiếu đến mẫu phù hợp trong văn bản thay thế.

Ví dụ, để so khớp từ đầu dòng đến at , hãy sử dụng lệnh sau:

  • sed 's/^.*at/REPLACED/' song.txt

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

Output
REPLACED never ends yes, it goes on and on, my friend some people started singing it REPLACED it was and they'll continue singing it forever just because...

Bạn có thể thấy rằng biểu thức ký tự đại diện khớp từ đầu dòng đến version cuối cùng của at .

Vì bạn không biết cụm từ chính xác sẽ khớp trong chuỗi tìm kiếm, bạn có thể sử dụng ký tự & để đại diện cho văn bản phù hợp trong chuỗi thay thế.

Hãy đặt dấu ngoặc đơn xung quanh văn bản phù hợp:

  • sed 's/^.*at/(&)/' song.txt

Bạn sẽ thấy kết quả nà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...

Một cách linh hoạt hơn để tham chiếu văn bản phù hợp là sử dụng dấu ngoặc đơn thoát để group các phần của văn bản phù hợp.

Mọi group văn bản tìm kiếm được đánh dấu bằng dấu ngoặc đơn đều có thể được tham chiếu bởi một số tham chiếu thoát. Ví dụ: group dấu ngoặc đơn đầu tiên có thể được tham chiếu với \1 , group thứ hai với \2 , v.v.

Trong ví dụ này, ta sẽ chuyển hai từ đầu tiên của mỗi dòng:

  • sed 's/\([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\)/\2 \1/' song.txt

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

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

Như bạn thấy , kết quả không hoàn hảo. Ví dụ: dòng thứ hai bỏ qua từ đầu tiên vì nó có một ký tự không được liệt kê trong bộ ký tự của ta . Tương tự, nó coi they'll là hai từ ở dòng thứ năm.

Hãy cải thiện biểu thức chính quy để chính xác hơn:

  • sed 's/\([^ ][^ ]*\) \([^ ][^ ]*\)/\2 \1/' song.txt

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

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

Lần này tốt hơn nhiều so với lần trước. Điều này group dấu câu với từ liên quan.

Lưu ý cách ta lặp lại biểu thức bên trong dấu ngoặc đơn (một lần không có ký tự * và sau đó một lần với nó). Điều này là do ký tự * trùng với bộ ký tự đứng trước nó không hoặc nhiều lần. Điều này nghĩa là kết quả trùng với ký tự đại diện sẽ được coi là "khớp" ngay cả khi không tìm thấy mẫu.

Để đảm bảo sed tìm thấy văn bản ít nhất một lần, bạn phải khớp nó một lần mà không có ký tự đại diện trước khi sử dụng ký tự đại diện.

Kết luận

Trong hướng dẫn này, bạn đã khám phá lệnh sed . Bạn đã in các dòng cụ thể từ file , tìm kiếm văn bản, các dòng đã xóa, overrides lên file root và sử dụng biểu thức chính quy để thay thế văn bản. Bạn có thể thấy cách bạn có thể nhanh chóng chuyển đổi một tài liệu văn bản bằng cách sử dụng các lệnh sed được xây dựng đúng cách.

Trong phần tiếp theo của loạt bài này , bạn sẽ khám phá một số tính năng nâng cao hơn.


Tags:

Các tin liên quan

Sedan trung gian: Thao tác các dòng văn bản trong môi trường 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