Cách thay thế một từ bằng dòng mới


11

Tôi có một tệp văn bản với dữ liệu sau và mỗi hàng kết thúc bằng |END|.

T|somthing|something|END|T|something2|something2|END|

Tôi đang cố gắng để thay thế |END|bằng \ndòng mới với sed.

 sed 's/\|END\|/\n/g' test.txt

Nhưng nó tạo ra đầu ra sai như dưới đây:

 T
 |
 s
 o
 m
 e
 ...

Nhưng điều tôi muốn là đây:

T|somthing|something
T|something2|something2

Tôi cũng đã thử với tr. Nó cũng không hoạt động.


Câu trả lời:


15

Dùng cái này:

sed 's/|END|/\n/g' test.txt

Những gì bạn đã cố gắng không hoạt động vì sed sử dụng các biểu thức chính quy cơ bản và triển khai sed của bạn có một \|toán tử có nghĩa là hoặc hoặc (một phần mở rộng phổ biến cho BRE), do đó, những gì bạn đã viết thay thế (chuỗi ENDtrống hoặc chuỗi trống) bằng một dòng mới.


Cần nhận xét \ in \ n: sed 's / | END | / \\ n / g
Baazigar

@Baazigar Không, những gì AB viết là chính xác (ít nhất là đối với Linux, một số triển khai sed sẽ phát ra \n). Câu hỏi hỏi làm thế nào để thay thế |END|bởi một dòng mới, không phải bởi \n.
Gilles 'SO- đừng trở nên xấu xa'

Các ký tự cho dòng mới là '\ n'. Cần có \ n vì \ cũng là một ký tự thoát, vì vậy nếu bạn chỉ làm \ n, bạn đang nói 'thoát ký tự n này'. Khi bạn làm \ n bạn đang nói 'đừng coi điều này tiếp theo \ như một lối thoát.'.
Baazigar

7

Sau đây làm việc tốt cho tôi:

$ sed 's/|END|/\
/g' foobar
T|somthing|something
T|something2|something2

Lưu ý rằng tôi chỉ cần đặt dấu gạch chéo ngược theo sau là phím enter.


2
Đó là cú pháp chuẩn. Sử dụng \n như trong câu trả lời của @ AB sẽ không hoạt động với một số sedtriển khai.
Stéphane Chazelas

@ StéphaneChazelas Việc triển khai sed nào hỗ trợ \|cho việc thay thế trong một biểu thức chính quy nhưng không \ncó nghĩa là dòng mới trong một sự sthay thế?
Gilles 'SO- ngừng trở nên xấu xa'

5

Bạn có thể sử dụng awk:

$ awk -F'\\|END\\|' '{$1=$1}1' OFS='\n' file
T|somthing|something
T|something2|something2
  • -F'\\|END\\|' đặt dấu phân cách trường thành |END|
  • OFS='\n' đặt dấu tách trường ouput thành dòng mới
  • $1=$1nguyên nhân awktái tạo lại $0với OFSnhư tách lĩnh vực
  • 1là một giá trị thực, gây ra awkin toàn bộ dòng đầu vào

3

Khác có thể lệnh và sử dụng RStùy chọn của nó sẽ là:

awk '$1=$1' RS="\|END\|" file

Sẽ in các bản ghi đó (dựa trên eparator R ecord S của awk) không trống (có ít nhất một trường) để ngăn in các dòng trống.

Đã thử nghiệm trên đầu vào này:

T|somthing|something|END|T|something2|something2|END|
Test|END|
|END|

Cung cấp đầu ra này:

T|somthing|something
T|something2|something2
Test

Điều đó đã xóa tất cả các dòng trống :) Nếu bạn cũng muốn có dòng mới, thay thế $1=$1bằng $0lệnh:

awk '$0' RS="\|END\|" file

$1=$1ngưng tụ các chuỗi khoảng trống thành một ký tự khoảng trắng và trả về false nếu trường đầu tiên bằng 0. Không có nghĩa. Bạn có thể muốn awk 1 RS='\\|END\\|'hoặc awk NF RS='\\|END\\|'hoặc awk length RS='\\|END\\|'ở đây. Lưu ý rằng RS regrec yêu cầu gawk hoặc mawk
Stéphane Chazelas

3

Một cách khác với sedđiều đó không in các dòng trống:

sed 's/|END|/\
/g;/^$/!P;D' infile

ví dụ: đầu vào:

T|one|two|END|T|three|four|END|
T|five|six|END|T|seven|eight|END|
T|nine|ten|END|T|eleven|twelve|END|

đầu ra:

T|one|two
T|three|four
T|five|six
T|seven|eight
T|nine|ten
T|eleven|twelve

điều tương tự với ed:

ed -s infile <<'IN'
1,$j
s/|END|/\
/g
,p
q
IN

1

Như đã đề cập ở đây bởi Walter Mundt , chúng ta có thể đạt được điều này bằng một chuỗi ANSI C trích dẫn

sed $'s/|END|/\\\n/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
$'s/|END|/\\\n/g'
T|somthing|something
T|something2|something2

~ $

Kiểm tra các liên kết ở trên ở đây cho các lựa chọn thay thế khác.

Bạn cũng có thể sử dụng cú pháp sau đây, tôi không chắc liệu nó có hoạt động trên tất cả các hương vị của Unix / Linux không

sed 's/|END|/\'$'\n''/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
's/|END|/\'$'\n''/g'
T|somthing|something
T|something2|something2

~ $

Làm việc trên FreeBSD v10. Trên thực tế, chỉ có phương pháp làm việc cho tôi. Cảm ơn bạn.
Sopalajo de Arrierez

0

Tôi đã có một vấn đề tương tự trong vỏ posix nghiêm ngặt Tôi đã làm điều đó trong hai lần với một char không sử dụng

cat data.json|tr '§' '?'|sed -e 's/"[^"]":/§&/g'|tr '§' '\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.