Làm cách nào để ngăn sed thêm các ký tự dòng mới


17

Tôi đang chạy 2 sedlệnh sau. Cái đầu tiên thêm các ký tự dòng mới nơi tôi muốn chúng, cái thứ hai cũng thêm các ký tự dòng mới nơi tôi muốn chúng, nhưng NHƯNG cũng thêm một ký tự ở cuối tệp không có ký tự trước.

sed -e 's|\<LIST_G_STATEMENT>|&\
|g' ${XMLDIR}/statement_tmp_1.xml > ${XMLDIR}/statement_tmp_2.xml

sed -e 's|\</LIST_G_STATEMENT>|&\
|g' ${XMLDIR}/statement_tmp_2.xml > ${XMLDIR}/statement_tmp_3.xml

Sử dụng od -ctrên cả 3 tệp cho kết quả đầu ra sau.

statement_tmp_1.xml (không có \nở cuối tệp)

1314700    T   A   T   E   M   E   N   T   >   <   /   L   I   S   T   _
1314720    G   _   S   T   A   T   E   M   E   N   T   >   <   /   G   _
1314740    S   E   T   U   P   >   <   /   L   I   S   T   _   G   _   S
1314760    E   T   U   P   >   <   /   A   R   X   S   G   P   O   >
1314777

statement_tmp_2.xml (không có \nở cuối tệp)

1314700    S   T   A   T   E   M   E   N   T   >   <   /   L   I   S   T
1314720    _   G   _   S   T   A   T   E   M   E   N   T   >   <   /   G
1314740    _   S   E   T   U   P   >   <   /   L   I   S   T   _   G   _
1314760    S   E   T   U   P   >   <   /   A   R   X   S   G   P   O   >
1315000

statement_tmp_3.xml ( \nở cuối tệp - nó đến từ đâu?)

1314700    S   T   A   T   E   M   E   N   T   >   <   /   L   I   S   T
1314720    _   G   _   S   T   A   T   E   M   E   N   T   >  \n   <   /
1314740    G   _   S   E   T   U   P   >   <   /   L   I   S   T   _   G
1314760    _   S   E   T   U   P   >   <   /   A   R   X   S   G   P   O
1315000    >  \n
1315002

Tôi đang chạy AIX 5.3

Về cơ bản, tôi muốn nó dừng thêm phần bổ sung \nhoặc tìm cách loại bỏ nó.


Chỉ là một câu hỏi: tại sao bạn sử dụng một dòng mới theo nghĩa đen trong mẫu thay thế của bạn khi bạn có thể đã sử dụng s|...|&\n|tốt như vậy?
Joseph R.

1
@JosephR. \nở phía bên tay phải là không di động.
Stéphane Chazelas

@StephaneChazelas Thật kỳ lạ. Đây có phải là một điều CR vs CRLF?
Joseph R.

2
Một tệp không kết thúc bằng ký tự dòng mới không phải là tệp văn bản, vì vậy hành vi với các tiện ích văn bản trên chúng là không xác định . Sử dụng perlhoặc công cụ khác có thể đối phó với dữ liệu nhị phân.
Stéphane Chazelas

4
@JosephR. Không, \<LF>là cách truyền thống và POSIX để thêm ký tự LF. \nthường sẽ thay thế một nký tự trong bất cứ thứ gì trừ GNU sed.
Stéphane Chazelas

Câu trả lời:


10

Bạn nên xem xét bản thân mình may mắn khi AIX sedđã thêm các ký tự dòng mới bị thiếu.

Tệp không trống không kết thúc bằng ký tự dòng mới không phải là tệp văn bản (ít nhất là theo định nghĩa POSIX của tệp văn bản) vì tệp văn bản có nghĩa là chứa các dòng và dòng là một (không quá- dài) chuỗi ký tự được chấm dứt bởi một ký tự dòng mới, vì vậy hành vi của các tiện ích văn bản như sedtrên nó là không xác định và trong thực tế thay đổi từ thực hiện đến thực hiện.

Một số sedthực hiện sẽ loại bỏ các nhân vật giả sau dòng cuối cùng.

AFAIK, xmlcác tệp có nghĩa là các tệp văn bản, vì vậy điều đó có nghĩa là sedchỉ sửa nó cho bạn.

Nếu bạn không cần tệp đó không kết thúc bằng ký tự dòng mới, thì bạn có thể sử dụng perlhoặc các công cụ khác có thể đối phó với dữ liệu phi văn bản.

perl -pe 's|<LIST_G_STATEMENT>|$&\n|g'

1
Dòng mới kết thúc hữu ích, nếu bạn muốn đưa sedđầu ra của mình vào bất kỳ tiện ích Unix tiêu chuẩn nào khác. Thành thật mà nói, tôi đã không nhận thấy sedđiều này trong nhiều năm , vì các thay thế lệnh vỏ Bourne như $(sed 's/bas/replac/' <<<'basement')cắt xén dòng mới cuối cùng, nếu có. Nhưng có những lúc bạn chắc chắn không muốn nó; ví dụ , thao tác văn bản clipboard X với sed. FYI, GNU sed, nếu có, không thêm một dòng mới kết thúc nếu bạn sử dụng pnó với -ntùy chọn, như được mô tả trong câu trả lời SE này .
TheDudeAdides

0

Đây là một cách để xóa dòng mới cuối cùng khỏi tệp bằng cách sử dụng dd:

printf "" | dd  of='/path/to/file' seek=<filesize_in_bytes - 1> bs=1 count=1

Để kiểm tra xem một tệp kết thúc bằng một dòng mới, bạn có thể sử dụng:

tail -c 1 /path/to/file | tr -dc '\n' | wc -c

Và để có được kích thước tệp theo byte sử dụng:

wc -c < /path/to/file

0

Theo này AIX của nhãn hiệu IBM tailkhông -reverse - trông khá mát mẻ. Miễn là tệp của bạn dưới 20KB, các mục sau sẽ hoạt động:

tail -r <file | dd bs=1 skip=1 | tail -r >file.new
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.