Sed - thay thế một nhân vật trong một dòng phù hợp tại chỗ?


21

Trong một tệp chứa các dòng như thế này:

# lorem ipsum blah variable

Tôi muốn xóa #(bình luận) ký tự trong cùng một dòng có chứa một chuỗi cụ thể. Có sedtốt cho việc này không?

Tôi đang đấu tranh để có được điều kiện làm việc này. Tôi có một cách "vụng về" để làm việc này; Tôi có thể tìm thấy số dòng phù hợp với awkhoặc sedsau đó sử dụng số này trong một sedlệnh riêng biệt , nhưng tôi tin rằng điều này có thể được thực hiện theo cách tốt hơn nhiều.

Câu trả lời:


36

Sử dụng chuỗi bạn đang tìm kiếm làm bộ chọn cho các dòng được vận hành theo:

sed '/ipsum/s/#//g'

/ipsum/chọn các dòng có chứa "ipsum" và chỉ trên các dòng này, các lệnh tiếp theo được thực thi. Bạn có thể sử dụng dấu ngoặc nhọn để chạy nhiều lệnh hơn

/ipsum/{s/#//g;s/@/-at-/g;}

4
Tôi đồng ý; đây là câu trả lời tốt nhất (mặc dù không phải là duy nhất). Nhận xét: (1) 's/#//g'sẽ xóa tất cả các #ký tự trong dòng. Nếu đó không phải là những gì bạn muốn, hãy xóa g(viết tắt của cụm từ toàn cầu). (2) Để chỉnh sửa một tập tin tại chỗ (như được yêu cầu trong câu hỏi), sử dụng sed -i.
G-Man nói 'Phục hồi Monica'

2
(3) Đối với các tình huống trong thế giới thực, nếu bạn muốn bỏ bình luận một dòng, bạn có thể muốn sử dụng sed -i '/ipsum/s/#[[:space:]]*//', để loại bỏ bất kỳ khoảng trắng và tab nào ngay sau đó #. (4) Bạn cũng có thể muốn xem xét xác minh rằng đó #là ký tự không trống đầu tiên trong dòng. Lệnh hiện tại sẽ xóa #từ dòng prompt "Enter # of ipsums:".
G-Man nói 'Phục hồi Monica'

1
@ G-Man - sự bổ sung tuyệt vời! Đến pt thứ 2 của bạn (không gian hàng đầu), còn: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^biểu thị bắt đầu của dòng, $cho cuối dòng) - ít nhất là trong gnu sed ...
Jeremy Davis

1
@JeremyDavis: Vâng, bạn có thể neo regex vào đầu dòng với ^, nhưng điều đó sẽ sai. Tôi thường nhận xét mã thụt lề bằng cách đặt mã #ngay trước mã, vì vậy mã #được thụt vào. Tôi nghi ngờ rằng tôi là người duy nhất làm điều đó.
G-Man nói 'Phục hồi Monica'

1
@ G-Man - ah vâng, tất nhiên! Cảm ơn, tôi đã không xem xét điều đó. Vì vậy, bạn cũng muốn kiểm tra khoảng trắng giữa ^& #, vì vậy một cái gì đó giống như thế này : /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. Mặc dù sau đó, tùy thuộc vào vị trí của #nó, nó vẫn có thể gây ra sự cố (ví dụ: trong các ngôn ngữ sử dụng thụt lề / tách khoảng trắng).
Jeremy Davis

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

sau đó:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

cho:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Nó hoạt động như sau:

snói sedrằng nó nên thay thế những gì biểu thức thông thường tìm thấy.

Mẫu được # \(.*blue.*\)chia thành: Tìm một hàm băm theo sau là khoảng trắng. Dấu ngoặc ( \() bắt đầu nhóm. .*blue.*là từ bluevới bất cứ điều gì trước và sau. Dấu ngoặc tiếp theo ( \)) đóng nhóm.

Sự thay thế là \1một tham chiếu ngược đến nội dung của khung nhóm đầu tiên.


3

Bạn có thể sử dụng Vim trong chế độ Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s thay thế

  2. x lưu và đóng


Điều đó thật tuyệt. Tôi không biết về điều đó! TBH, tôi không chắc đó là câu trả lời hay nhất cho câu hỏi này (IMO câu trả lời sed hàng đầu là câu trả lời) nhưng nó vẫn rất tuyệt! Cảm ơn vì đăng.
Jeremy Davis
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.