Tôi có một tài liệu với rất nhiều dòng trống.
Làm thế nào tôi có thể loại bỏ chúng khi có 2 hoặc nhiều hơn với nhau.
Tôi đã thử sed "s/\n\n//"
tập tin nhưng nó không hoạt động. Không có lỗi.
Tôi có một tài liệu với rất nhiều dòng trống.
Làm thế nào tôi có thể loại bỏ chúng khi có 2 hoặc nhiều hơn với nhau.
Tôi đã thử sed "s/\n\n//"
tập tin nhưng nó không hoạt động. Không có lỗi.
Câu trả lời:
Chỉ để xóa các dòng trống:
sed '/^$/d'
sed
được định hướng theo dòng, do đó, suy nghĩ theo nghĩa "2 hoặc nhiều hơn một byte cụ thể" hoạt động trừ khi byte đó là một dòng mới. Sau đó, bạn phải nghĩ ra một cái gì đó hoạt động cho toàn bộ dòng.
sed
có khả năng xử lý một số dòng thông qua tính năng "không gian mẫu" / "không gian giữ". Nhưng tôi cảm thấy điều đó quá phức tạp. ;-)
1!
(khớp với tất cả ngoại trừ dòng 1), do đó : sed '1!{/^$/d'}
.
sed
. Tạo một tệp về cơ bản sẽ xóa bất kỳ tệp hiện có cùng tên. sed '/^&/d' file.txt > otherfile.txt
sẽ làm việc.
Không cần sed
. grep
sẽ làm:
grep .
(đó là grep
SPC, dấu chấm, khớp với bất kỳ dòng nào chứa ít nhất một ký tự).
Ngoài ra còn có:
tr -s '\n'
(ép bất kỳ chuỗi ký tự dòng mới thành một).
Như Chris đã lưu ý, cả hai đều không tương đương vì loại bỏ các dòng trống (như giải pháp đầu tiên ở trên và hầu hết các câu trả lời khác tập trung vào đây) không giống như việc ép các chuỗi ký tự dòng mới theo yêu cầu trong trường hợp dòng đầu tiên trống như nó chỉ mất một ký tự dòng mới hàng đầu để làm cho dòng đầu tiên trống.
Đã thấy câu trả lời của @Bruce Ediger sed
không phải là công cụ tốt nhất cho điều đó, vì nó dựa trên dòng và được coi \n
là ký tự cuối dòng, điều này trở nên phức tạp.sed
có thể là công cụ hoàn hảo cho công việc, tuy nhiên, đây là một số tùy chọn khác:
Perl
perl -ne 'print if /./' file.txt
hoặc là
perl -pe '$/=""; s/\n+/\n/;' file.txt
Cảm ơn @ruakh đã khiến tôi đi và đọc nó :
$ /
Dấu tách bản ghi đầu vào, dòng mới theo mặc định. Điều này ảnh hưởng đến ý tưởng của Perl về "đường kẻ" là gì. Hoạt động như biến RS của awk, bao gồm xử lý các dòng trống làm đầu cuối nếu được đặt thành chuỗi null (một dòng trống không thể chứa bất kỳ khoảng trắng hoặc tab nào). Bạn có thể đặt chuỗi đó thành một chuỗi nhiều ký tự để khớp với một đầu cuối nhiều ký tự hoặc không xác định để đọc đến cuối tệp. Đặt nó thành "\ n \ n" có nghĩa là một cái gì đó hơi khác so với cài đặt thành "", nếu tệp chứa các dòng trống liên tiếp. Đặt thành "" sẽ coi hai hoặc nhiều dòng trống liên tiếp thành một dòng trống đơn. Đặt thành "\ n \ n" sẽ mù quáng cho rằng ký tự đầu vào tiếp theo thuộc về đoạn tiếp theo, ngay cả khi đó là một dòng mới.
gawk / awk
awk '$1' file.txt
Điều đó sẽ làm việc cho ví dụ được đăng nhưng như @Stephane Chazelas đã chỉ ra, nó cũng sẽ xóa các dòng có trường đầu tiên "trông giống như" 0
. Điều này mạnh mẽ hơn:
awk NF file.txt
perl -pe 's/\n+/\n/ file.txt
sẽ làm, phân tách bản ghi đầu vào là không liên quan cho việc sử dụng này.
perl -pe
hoặc perl -ne
làm việc theo dòng. \n+
sẽ không bao giờ khớp bởi vì nó chỉ được áp dụng trên một dòng duy nhất. Đó là lý do tại sao bạn cần phải thiết lập $/
hoặc sử dụng -0
ti để xóa toàn bộ tệp : perl -0pe 's/\n+/\n/' file
.
Bạn có ý nghĩa gì để loại bỏ? xóa trùng lặp (nhiều dòng trống thành một) hoặc xóa tất cả?
Nếu bạn muốn loại bỏ trùng lặp, đây là phương pháp sử dụng sed:
sed '$!N; /^\(.*\)\n\1$/!P; D'
Nó mô phỏng uniq
lệnh.
Sự lựa chọn tốt nhất là sử dụng awk
:
awk NF <filename>
sed
này hoạt động rất tốt! Đề nghị này là một câu trả lời tốt nhất.
Đối với hầu hết các câu trả lời này, trước tiên cần phải xóa khoảng trắng ở cuối. Loại bỏ các dòng mới tăng gấp đôi sẽ loại bỏ tất cả các dòng trống. (Nghĩ về điều này).
Theo nghĩa đen, OP muốn "tất cả các dòng trống được xóa khỏi một tệp nếu có bất kỳ dòng trống lặp lại nào".
Người dùng thông thường muốn "chỉ xóa các dòng trống trùng lặp".
Để làm điều này, trước tiên hãy vạch ra dấu vết trắng và đường ống mặc dù con mèo
sed s/[[:space:]]*$// | cat -s
Tuy nhiên, điều này sẽ không loại bỏ một dòng trống hàng đầu hoặc dấu vết thừa.
Nếu bạn muốn giữ một dòng trống duy nhất cho bất kỳ chuỗi trống nào, bạn có thể làm:
sed -e '/./b' -e :n -e 'N;s/\n$//;tn'
cat -s
) thực sự hoàn thành chính xác những gì câu hỏi được hỏi khi tôi hiểu nó. (Và nó tốt hơn là cat -s
vì tôi có thể sử dụng sed -i
với nó.)
Hãy thử sed -e 's#\\n\\n#\\n#g' input.file > output.file
sử dụng /
cả hai như dấu tách trường và một phần của biểu thức chính quy của bạn có thể là vấn đề.
Sử dụng lệnh này:
tr -s '\r' '\n'
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. Lệnh tr
sẽ dịch tất cả \r
sang \n
và sau đó sẽ ép tất cả \n
thành chỉ một. Vì vậy, nó hoạt động, không biết phải làm gì với thực tế là điều này áp dụng cho windows chứ không phải UNIX.