2012-03-13 30 views
9

Tôi đang sử dụng một kịch bản rất đơn giản sed loại bỏ ý kiến: sed -e 's/--.*$//'Có. thực sự phù hợp với bất kỳ nhân vật nào?

Nó hoạt động tuyệt vời cho đến khi ký tự khác ASCII có mặt trong một bình luận, ví dụ .: -- °. Dòng này không khớp với cụm từ thông dụng và không được thay thế.

Bất kỳ ý tưởng nào về cách nhận . để thực sự khớp với bất kỳ ký tự nào?


Giải pháp:

Kể từ file nói nó là một văn bản iso8859, LANG biến môi trường phải được thay đổi trước khi gọi sed: LANG=iso8859 sed -e 's/--.*//' -

Trả lời

2

@ julio-Guerra: Tôi chạy vào một tình huống tương tự, cố gắng để xóa dòng như folowing (chú ý nhân vật Æ) :

--MP_/yZa.b._zhqt9OhfqzaÆC

trong một tập tin, sử dụng

sed 's/^--MP_.*$//g' my_file

Mã hóa tập tin chỉ định bởi các lệnh Linux file

file my_file: ISO-8859 text, with very long lines 
file -b my_file: ISO-8859 text, with very long lines 
file -bi my_file: text/plain; charset=iso-8859-1 

tôi đã cố gắng giải pháp của bạn, với hoán vị khác nhau (thông minh!); ví dụ:

LANG=ISO-8859 sed 's/^--MP_.*$//g' my_file

nhưng không ai trong số đó hoạt động. Tôi đã tìm thấy hai cách giải quyết:

  1. Biểu thức sau Perl được thực hiện, tức làxóa dòng đó:

perl -pe 's/^--MP_.*$//g' my_file

[Đối với một lời giải thích của -pe công tắc dòng lệnh, hãy tham khảo câu trả lời StackOverflow này:

Perl flags -pe, -pi, -p, -w, -d, -i, -t?]

  1. Cách khác, sau khi chuyển đổi mã hóa tệp thành UTF-8, biểu thức sed hoạt động (ký tự còn lại Æ, nhưng giờ đã được mã hóa UTF8):

iconv -f iso-8859-1 -t utf8 my_file > my_file.utf8

Như tôi đang làm việc với rất nhiều (1000) của email với mã hóa khác nhau, mà trải qua chế biến trung gian (chuyển đổi bash-kịch bản sang UTF-8 không luôn hoạt động), vì mục đích của tôi "Giải pháp 1 "ở trên có lẽ sẽ là giải pháp mạnh mẽ nhất.

Ghi chú:

  • sed (GNU sed) 4.4
  • perl v5.26.1 xây dựng cho x86_64-linux-thread-đa
  • hệ thống x86_64
  • Arch Linux
0

Các tài liệu của Lệnh sed2 z của GNU sed đề cập đến hiệu ứng này (nhấn mạnh của tôi):

Lệnh này làm trống nội dung của không gian mẫu. Nó thường là giống như 's /.*//', nhưng hiệu quả hơn và hoạt động trong sự hiện diện của của chuỗi multibyte không hợp lệ trong luồng đầu vào. POSIX yêu cầu rằng các chuỗi như vậy là không phải khớp với '.', sao cho không có cách di động để xóa bộ đệm của sed ở giữa tập lệnh ở hầu hết các ngôn ngữ đa byte (bao gồm cả ngôn ngữ UTF-8).

Dường như bạn đang chạy sed trong miền địa phương UTF-8 (hoặc đa byte khác). Bạn sẽ muốn đặt LC_CTYPE (có kích thước nhỏ hơn LANG và sẽ không ảnh hưởng đến bản dịch của thông báo lỗi. Tên địa phương hợp lệ thường trông giống như en.iso88591 hoặc (đối với vị trí trong tiểu sử của bạn) fr_FR.iso88591, không chỉ mã hóa - bạn có thể có thể xem danh sách đầy đủ với locale -a

Ví dụ:

LC_CTYPE=fr_FR.iso88591 sed -e 's/--.*//' 

ngoài ra, nếu bạn biết rằng những phần không bình luận của dòng chỉ chứa ASCII, bạn có thể chia. dòng tại điểm đánh dấu nhận xét, in phần đầu tiên và loại bỏ phần còn lại:

sed -e 's/--/\n/' -e 'P' -e 'd' 
Các vấn đề liên quan