Thay thế \ n bằng một dòng mới trong sed


23

Tôi rất bối rối với vô số tùy chọn của GNU sed, POSIX sedvà BSD sed. Làm cách nào để thay thế chữ \nbằng ký tự dòng mới bằng ba sedloại này?


Họ có nhiều thứ khác nhau, bạn muốn biết phần nào?
cuonglm

@ Tôi nghĩ bây giờ thì rõ rồi.
Avinash Raj

1
Bạn đã có một cái nhìn về câu hỏi này ?
Groxxda

2
Những gì bạn muốn xảy ra trên đầu vào như foo\\nbarhay foo\\\nbar?
Gilles 'SO- ngừng trở nên xấu xa'

đơn giản, foo \\ trong dòng tiếp theo nó sẽ là thanh.
Avinash Raj

Câu trả lời:


30
sed 's/\\n/\
/g'

Lưu ý dấu gạch chéo ngược ngay trước khi nhấn return trong chuỗi thay thế.


cái này có hiệu quả với tất cả các loại sed không?
Avinash Raj

Tôi tin rằng nó nên; Tôi chỉ thử nghiệm trên Linux bằng phiên bản gnu.
unxnut

11
@AvinashRaj. Đó là POSIX và đã làm việc với sedlệnh ban đầu trong Unix v7 vào năm 1979. Nơi duy nhất có thể không hoạt động sẽ là các triển khai tước bỏ POSIX sedgiống như một số ứng dụng dựa trên hộp bận bị loại bỏ. Điều đó sẽ không hoạt động trong csh nhưng đó là một vấn đề csh.
Stéphane Chazelas

\\nđược sử dụng trong phần tìm kiếm, tại sao không sử dụng \ntrong phần thay thế? cái trước dường như ngụ ý cái sau tồn tại. I E. tại sao không phải thế này$ echo '1\n2'|sed 's/\\n/\n/g'

Trong trường hợp này, \nlà một nghĩa đen, ngụ ý rằng nó xuất hiện dưới dạng hai ký tự: abackslash theo sau n, và không phải là một ký tự dòng mới. Do đó, hai dấu gạch chéo ngược để tạo dấu gạch chéo ngược thành chữ và sau đón
unxnut

9

Vì bạn đã có sedcâu trả lời di động của mình , tôi sẽ chỉ đề cập rằng đó sedhiếm khi là công cụ tốt nhất nếu bạn cần bằng cách nào đó thao tác các dòng mới. Perl rất gần như di động sed, được cài đặt theo mặc định trên hầu hết các hệ thống * nix và có thể giải quyết vấn đề này rất dễ dàng:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

Một lựa chọn rất di động khác là awk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

Trên Solaris, hãy nhớ sử dụng awk tiêu chuẩn trong / usr / xpg4 / bin, một trong / bin là một lịch sử và không nên được sử dụng cho các tập lệnh mới.


Tôi muốn nói awkcó vấn đề về tính di động tương tự (Là awkđơn giản cũ của tôi awk, nawkhoặc gawk?). Trên thực tế, phiên bản trong hộp Solaris của tôi thiếu gsub(). Phiếu bầu của tôi ở đây là dành cho Perl ( perl -nlawe '...'xấp xỉ hành vi tự động của awk).
arielCo

2
@arielCo: Đối với awktính di động, hãy awksử dụng phiên bản tuân thủ POSIX và chỉ sử dụng các tính năng đó và bạn sẽ ổn. Trên Solaris bạn sẽ tìm thấy một như /usr/xpg4/bin/awk.
Scrutinizer


@arielCo thực sự, awk dễ mang theo hơn perl. Cách tiếp cận awk thứ hai của tôi không sử dụng gsub()sẽ hoạt động ở mọi nơi. Ngay cả busybox cũng có awk.
terdon

1
gsub () là POSIX (gsub, đã được thêm vào trong SVR3.1, POSIX awk dựa trên SVR4 với một vài bổ sung xem hướng dẫn gawk để biết thêm thông tin), gensub () là phần mở rộng GNU. Awk ban đầu vẫn được tìm thấy là / bin / awk trên Solaris, không hỗ trợ gsub (), nhưng cũng không hỗ trợ FS đa nhân vật.
Stéphane Chazelas

1

Nếu Holdspace trống, bạn cũng có thể làm:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

... nhưng câu trả lời của uxnut đã nhanh hơn và đơn giản hơn, vì vậy bạn có thể thực hiện theo ý muốn.

Một khả năng ngoại lai khác:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

Nhưng hãy cẩn thận, ^ dịch tất cả các \dấu gạch chéo ngược kiểu C tiêu chuẩn - như \backspace và \return \00và octals và whathaveyou.



-2

Bạn cần một giải pháp trong sed, và điều đó đã được đưa ra dưới đây. Nhưng tôi muốn thêm một khả năng nữa là IMHO chỉ dễ dàng hơn và nhanh hơn,

tr -d "\n"

1
cái này làm gì xóa tất cả các dòng mới từ đầu vào?
mikeerv

Vâng, đó chính xác là những gì nó làm
jpmuc

5
nhưng tại sao? Điều đó có liên quan gì đến câu hỏi?
mikeerv

1
Điều này chỉ xóa "\ n" khi câu hỏi đang hỏi cách thay thế chuỗi "\ n" bằng các dòng mới thực tế.
spuder
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.