sed không thể loại bỏ ký tự dòng mới


12

Tôi đã sử dụng được sedmột thời gian nhưng đây là một vấn đề tôi không thể giải quyết được.

Hãy để tôi giải thích vấn đề của tôi với trường hợp thực tế.


Cảnh 1

printf "ls" | xclip -selection clipboard
echo "ls" | xclip -selection clipboard

Trong lệnh đầu tiên, tôi dẫn printfđầu ra để xclipnó được sao chép vào bảng tạm. Bây giờ, printfkhông giống như echokhông chèn một dòng mới vào cuối theo mặc định. Vì vậy, nếu tôi dán nội dung này vào terminal, lslệnh được sao chép sẽ không tự động chạy.

Trong phần thứ hai, có một dòng mới ở cuối, do đó, dán nội dung clipboard cũng dẫn đến việc chạy lệnh trong bảng tạm.

Điều này là không mong muốn đối với tôi. Vì vậy, tôi muốn xóa dòng mới bằng cách sử dụng sed, nhưng nó đã thất bại, như được giải thích trong cảnh bên dưới.

Cảnh # 2

echo "ls" | sed -r 's/\n//g' | xclip -selection clipboard

Nội dung trong clipboard vẫn chứa dòng mới. Khi tôi dán nó vào terminal, lệnh sẽ tự động chạy.

Tôi cũng đã cố gắng loại bỏ nhân vật trở về \r. Nhưng nada. Có vẻ như tôi đang thiếu một cái gì đó rất quan trọng / cơ bản ở đây.

Câu trả lời:


16

sedphân định trên \newlines - chúng luôn bị xóa trên đầu vào và được đặt lại trên đầu ra. Không bao giờ có một \nký tự ewline trong một sedkhông gian mẫu không xảy ra do chỉnh sửa bạn đã thực hiện. Lưu ý: với ngoại lệ của GNU sed's -zchế độ ...

Chỉ cần sử dụng tr:

echo ls | tr -d \\n | xclip -selection clipboard

Hoặc, tốt hơn nữa, hãy quên sedhoàn toàn:

printf ls | xclip -selection clipboard

Điều này sẽ loại bỏ tất cả các dòng mới, thường không mong muốn trong generate-text | xcliptrường hợp. Câu trả lời này chỉ loại bỏ dòng mới nhất.
Tom Hale

7

Nhiều công cụ xử lý văn bản, bao gồm cả sed, hoạt động trên nội dung của dòng, ngoại trừ ký tự dòng mới. Điều đầu tiên sed làm khi xử lý một dòng là loại bỏ dòng mới ở cuối, sau đó nó thực thi các lệnh trong tập lệnh và nó thêm một dòng mới cuối cùng khi in ra. Vì vậy, bạn sẽ không thể loại bỏ dòng mới với sed.

Để xóa tất cả các dòng mới, bạn có thể sử dụng trthay thế:

echo "ls" | tr -d '\n' | xclip


4

Bạn có thể thay thế dòng mới trong sed bằng cách chuyển qua tùy chọn -z .

sed -z 's/\n/ /g'

Trang người đàn ông quyến rũ:

-z, --null-data các dòng riêng biệt theo các ký tự NUL


Điều này sẽ loại bỏ tất cả các dòng mới, thường không được mong muốn trong | xcliptrường hợp.
Tom Hale

2

Nếu bạn chỉ đặt lệnh trong clipboard

echo -n "ls " | xclip -selection clipboard

Nếu bạn cần thêm các biến đổi phức tạp hơn,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard

Hừm. Dung dịch mịn. Tôi đoán có lẽ đã đến lúc chuyển sang perl hoặc python cho regex.
shivams

3
@shivams - perlpythoncả hai đều chậm hơn nhiều so với sedkhi được sử dụng đúng cách. Học cách sử dụng nó một cách chính xác là chìa khóa, mặc dù.
mikeerv

@mikeerv - Tôi đồng ý; đặc biệt cho oneliner sed là tuyệt vời. Nếu các phép biến đổi sẽ trở nên phức tạp hơn, thì tôi thích perl / python / gawk.
JJoao

1
@JJoa: Sở thích của bạn là của riêng bạn, nhưng sedcó thể làm được nhiều hơn là chỉ xử lý một lớp lót của bạn và nó có thể thực hiện nhanh hơn bất kỳ công cụ nào khác mà bạn đề cập.
mikeerv

1
@mikeerv - Một lần nữa, tôi đồng ý với bạn. Vài năm trước tôi có một hệ thống dịch thuật EN-PT được viết bằng sed (20000 s /.../.../), được tạo bởi sed! Va no đa hoạt động! Sau này, nó trở thành Perl, để có mảng, băm, hàm, gói và CPAN.
JJoao

1

Để chỉ xóa dòng mới nhất , hãy chuyển qua:

sed -z '$ s/\n$//'

sedsẽ không thêm \0vào cuối luồng nếu bộ phân cách được đặt thành NULthông qua -z, trong khi đó để tạo tệp văn bản POSIX (được xác định là kết thúc bằng a \n), nó sẽ luôn xuất ra một bản cuối cùng \nmà không có -z.

Ví dụ:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

Và để chứng minh không NULthêm:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72                        foo.bar

Để xóa nhiều dòng mới , hãy bỏ qua:

sed -Ez '$ s/\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.