Xóa ký tự thứ hai đến ký tự cuối cùng trong mỗi dòng - với sed


7

Làm cách nào để xóa ký tự trước ký tự cuối cùng trong mỗi dòng trong một tệp?

Tôi đã thử sed 's/.$//' myfile1.txtloại bỏ ký tự cuối cùng của mỗi dòng myfile1.txt, nhưng tôi không chắc cách xóa ký tự áp chót trong mỗi dòng.

Câu trả lời:


10

Bạn có thể làm:

sed -E 's/.(.)$/\1/' file.txt  

Để chỉnh sửa tệp tại chỗ, không cần sao lưu:

sed -Ei 's/.(.)$/\1/' file.txt 

Để chỉnh sửa tệp tại chỗ, với tệp gốc được sao lưu với .bakphần mở rộng:

sed -Ei.bak 's/.(.)$/\1/' file.txt 

POSIX-ly:

sed 's/.\(.\)$/\1/' file.txt

8

Để HOÀN TOÀN giải thích lệnh di động (vì có người hỏi) để MỌI NGƯỜI có thể hiểu điều này:

sed 's/.\(.\)$/\1/' file.txt

Thứ nhất, "Rõ ràng": Dòng này bao gồm một tên lệnh ( sed) và hai đối số riêng biệt được truyền cho lệnh đó bởi shell. Các trích dẫn đơn bị tước đi bởi vỏ, vì vậy những gì sed"thấy" là đối số của nó là:

s/.\(.\)$/\1/

file.txt

Vì không có đối số nào sedbắt đầu bằng dấu gạch nối, nên nó không hiểu bất kỳ đối số nào là tùy chọn.

Đối số đầu tiên được hiểu là một lệnh chỉnh sửa sẽ được chạy và bất kỳ đối số nào khác (trong trường hợp này chỉ là một file.txt) , được hiểu là tên của các tệp để đọc văn bản được chỉnh sửa bởi lệnh chỉnh sửa (đối số đầu tiên) .

(Lưu ý rằng văn bản đã chỉnh sửa được ghi vào sed"đầu ra tiêu chuẩn", đó là trở lại thiết bị đầu cuối của bạn, cửa sổ dòng lệnh của bạn.

file.txtphải là tên tệp của tệp nằm trong thư mục là "thư mục làm việc hiện tại" của trình bao của bạn khi bạn thực hiện sedlệnh này . (Nếu bạn muốn lệnh hoạt động trên cùng một tệp bất kể thư mục làm việc hiện tại của shell của bạn là gì khi bạn chạy lệnh, hãy đọc "đường dẫn tuyệt đối.")


Bây giờ chúng ta sẽ tự giải mã lệnh chỉnh sửa:

s/.\(.\)$/\1/

Lệnh chỉnh sửa bắt đầu bằng chữ cái s, dành cho "thay thế". Từ ký tự theo sau "s" ( /trong trường hợp này), cho đến phiên bản tiếp theo của cùng một ký tự ( /một lần nữa), là mẫu được thay thế cho. Nói cách khác, nó chỉ định văn bản sẽ "trông như thế nào" sẽ được thay thế bằng cách sử dụng nó. Nó cho biết sedcách "biết" khi tìm thấy văn bản nên được thay thế (nên được thay thế).

Mẫu trong trường hợp này là:

.\(.\)$

(Thuật ngữ thích hợp thay cho "mẫu" thực sự là regex , ban đầu là viết tắt của "biểu thức chính quy". Tôi sẽ không đi sâu vào chủ đề rộng hơn của các biểu thức chính thức ở đây.)

Regex này bắt đầu bằng dấu chấm ( .), là "ký tự đại diện" với ý nghĩa "bất kỳ ký tự đơn lẻ nào". Nó khớp (mô tả, tượng trưng) bất kỳ ký tự đơn nào của văn bản.

Dấu gạch chéo ngược ( \) thường được sử dụng trong các lệnh shell và biểu thức chính dưới dạng ký tự "thoát". Nói chung, điều này có nghĩa là nó sẽ loại bỏ tầm quan trọng đặc biệt của ký tự theo sau nó hoặc nó thêm một ý nghĩa đặc biệt cho ký tự sau.

Trong trường hợp này, các dấu ngoặc đơn (cả ()) được thoát (nghĩa là trước dấu gạch chéo ngược) để thêm một ý nghĩa đặc biệt. Ý nghĩa đặc biệt của dấu ngoặc đơn thoát trong biểu thức chính sedlà bất kỳ văn bản nào khớp với phần của biểu thức chính giữa các dấu ngoặc đơn đều được "ghi chú" đặc biệt và có thể được gọi lại . Chúng ta sẽ quay lại vấn đề này sau (khi chúng ta quay lại nhóm này trong ngoặc đơn).

Dấu chấm ( .) trong ngoặc đơn lại khớp với bất kỳ ký tự đơn nào.

Ký hiệu đô la ( $) được gọi là neo và nó khớp với phần cuối của dòng văn bản. Nếu không có neo này, regex sẽ chỉ khớp hai ký tự bất kỳ (cụ thể là nó sẽ khớp với hai ký tự đầu tiên trên mỗi dòng văn bản được đọc từ tệp được gọi file.txt) và (do dấu ngoặc đơn thoát) sedsẽ "ghi chú" thứ hai của hai nhân vật để tham khảo lại sau này.

Vì regex được neo vào cuối dòng, hai dấu chấm phải khớp với hai ký tự cuối cùng trên mỗi dòng văn bản (và ký tự cuối cùng được ghi chú để tham chiếu lại sau).

Phần tiếp theo của lệnh s(thay thế) là từ phiên bản thứ hai của ký tự theo sau s(trong trường hợp này là dấu gạch chéo /), đến phiên bản thứ ba của ký tự theo sau s. Đây được gọi là mô hình thay thế. Nó chỉ định những gì sedsẽ đặt vào vị trí của văn bản phù hợp với mẫu tìm kiếm (biểu thức chính quy).

Trong trường hợp này, mẫu thay thế là:

\1

Một lần nữa, dấu gạch chéo ngược được sử dụng để thoát khỏi ký tự theo sau và trong trường hợp này, một lần nữa lại thêm một ý nghĩa đặc biệt thay vì lấy đi một ý nghĩa đặc biệt.

Dấu gạch chéo ngược theo sau là một chữ số (từ 1 đến 9) được gọi là dấu lùi. Đây là những gì đề cập đến văn bản phù hợp trong ngoặc đơn nhóm trong mẫu tìm kiếm. Vì chữ số là 1, điều này đề cập đến các dấu ngoặc đơn đầu tiên . (Trong trường hợp này, tất nhiên, chỉ có một nhóm như vậy.)

Tóm lại, lệnh chỉnh sửa này có nghĩa là sử dụng văn bản khớp trong các dấu ngoặc đơn đã thoát (là ký tự cuối cùng của dòng) để thay thế văn bản khớp với toàn bộ biểu thức tìm kiếm (là hai ký tự cuối cùng của dòng).

Hiệu ứng ròng là loại bỏ ký tự thứ hai đến cuối cùng khỏi mỗi dòng.

Hoặc, chính xác hơn, sedsẽ đọc trong từng dòng văn bản từ tệp được file.txttìm thấy trong thư mục làm việc hiện tại; đối với mỗi dòng, nó sẽ thay thế hai ký tự cuối cùng của dòng bằng ký tự cuối cùng duy nhất của dòng đó; và nó sẽ in từng dòng sửa đổi thành đầu ra tiêu chuẩn của nó .

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.