Xóa dòng trống bằng sed


349

Tôi đang cố gắng xóa các dòng trống bằng sed:

sed '/^$/d'

nhưng tôi không có may mắn với nó

Ví dụ: tôi có những dòng này:

xxxxxx


yyyyyy


zzzzzz

và tôi muốn nó giống như:

xxxxxx
yyyyyy
zzzzzz

Những gì nên được mã cho điều này?


2
Lệnh sed của bạn trông ổn, nó sẽ hoạt động
perreal

Lệnh trên sẽ không hoạt động ngay cả khi bạn không có dấu cách / tab nhưng kết thúc dòng CR + LF .
devnull

Câu trả lời:


627

Bạn có thể có khoảng trắng hoặc tab trong dòng "trống" của mình. Sử dụng POSIX lớp với sedđể loại bỏ tất cả các dòng chỉ chứa khoảng trắng:

sed '/^[[:space:]]*$/d'

Một phiên bản ngắn hơn sử dụng ERE, ví dụ với gnu sed:

sed -r '/^\s*$/d'

(Lưu ý rằng sed KHÔNG hỗ trợ PCRE.)


3
@HuStmpHrrr gnu sed hoàn toàn không hỗ trợ PCRE. đó là ERE với-r
Kent

8
OS X cần thiết sed -i "" '/^[[:space:]]*$/d' <filename>,
jww

@BernieReiter ^\s*$sẽ khớp với tất cả các dòng "trống", có nghĩa là trống ở đây, dòng không chứa ký tự hoặc dòng chỉ chứa các chuỗi trống (Ví dụ: khoảng trắng). Tất cả các dòng phù hợp sẽ được loại bỏ bởi sed, với dlệnh.
Kent

96

Tôi đang thiếu awkgiải pháp:

awk 'NF' file

Mà sẽ trở lại:

xxxxxx
yyyyyy
zzzzzz

Cái này hoạt động ra sao? Vì NFlà viết tắt của "số trường", các dòng đó trống có 0 fiedls, do đó awk đánh giá 0 thành Sai và không có dòng nào được in; tuy nhiên, nếu có ít nhất một trường, đánh giá là True và awkthực hiện hành động mặc định của nó: in dòng hiện tại.


1
Whoah. Thậm chí còn chạy với phiên bản awk "thu nhỏ" của BSD (phiên bản 20121220 (FreeBSD). Cảm ơn :-)
Bernie Reiter

@BernieReiter bạn được chào đón :) Vâng, đây là một thành ngữ rất cơ bản mà tất cả các phiên bản awk cho phép.
fedorqui 'SO ngừng làm hại'

Và nó nhanh hơn rất nhiều mặc dù - đối với một bài kiểm tra nhanh và bẩn - tôi đang gọi awk hai lần: $ time (topic companies <data.tpx | awk 'NF' - | awk -f dialog_menu.awk -) real 0m0.006s user 0m0.000s sys 0m0.008s $ time (topic companies <data.tpx | gsed '/^\s*$/d' | awk -f dialog_menu.awk -) real 0m0.014s user 0m0.002s sys 0m0.006s Bạn có biết một cách tiện lợi để đưa điều này vào một kịch bản awk như, ví dụ, một mô hình không? awk '/ mypotype / {do Stuff ...}'
Bernie Reiter

@BernieReiter bạn có thể nói awk 'NF {do stuff...}'.
fedorqui 'SO ngừng làm hại'

1
Lưu ý rằng điều này cũng sẽ bỏ qua các dòng chỉ có khoảng trắng.
wvducky

60

sed '/^$/d'Sẽ ổn thôi, bạn có định sửa đổi tập tin không? Nếu vậy bạn nên sử dụng -icờ.

Có thể những dòng đó không trống, vì vậy nếu đó là trường hợp, hãy xem câu hỏi này Xóa các dòng trống khỏi txtfiles, xóa khoảng trắng khỏi đầu và cuối dòng Tôi tin rằng đó là những gì bạn đang cố gắng đạt được.


Đúng. tôi đang sửa đổi một tập tin. * .csv. Làm thế nào các -i nên được đặt vào lệnh sed?
jonas

2
sed -i '/^$/d'là một cách để làm điều đó.
Alberto Zaccagni

49

1
Những xuất hiện một cách chính xác trong công cụ trực tuyến của bạn, nhưng []nên không thể trốn thoát trong một biểu thức khung, vì vậy mã ở đây là không đúng cho \[\[:space:\]\]hay \[ \t\]- nên [[:space:]][ \t].
Benjamin W.

1
@BenjaminW. Cảm ơn đã nắm bắt điều đó. Đó không phải là từ tác giả gốc, mà đến từ Chỉnh sửa 3 khi nó được thay đổi từ văn bản thông thường thành "mã", sau đó "phơi bày" `` `thoát. Tôi đã sửa chúng bây giờ.
wvducky

30

Tôi tin rằng đây là cách dễ nhất và nhanh nhất:

cat file.txt | grep .

Nếu bạn cũng cần bỏ qua tất cả các dòng khoảng trắng thì hãy thử điều này:

cat file.txt | grep '\S'

Thí dụ:

s="\
\
a\
 b\
\
Below is TAB:\
    \
Below is space:\
 \
c\
\
"; echo "$s" | grep . | wc -l; echo "$s" | grep '\S' | wc -l

đầu ra

7
5

5
Không cần cat, cũng greplấy các tập tin:grep . file.txt
Ciro Santilli 冠状 病 六四 16/05/2016

3
Vâng, tôi biết, nhưng câu hỏi ban đầu không đề cập đến việc nguồn là tệp hay cái gì khác, vì vậy giải pháp là cái gì xuất hiện sau "|" và trước đó chỉ là ví dụ về nguồn. Đơn giản chỉ cần phân biệt giải pháp với nguồn của dòng.
Vadim

2
grep '\S'chắc chắn không phải là di động. Nếu bạn có grep -Pthì bạn có thể sử dụng grep -P '\S'nhưng nó cũng không được hỗ trợ trên tất cả các nền tảng.
tripleee

Nhược điểm của grep .so với các giải pháp khác là nó sẽ làm nổi bật tất cả các văn bản màu đỏ. Các giải pháp khác có thể bảo tồn các màu gốc. So sánh unbuffer apt search foo | grep .vớiunbuffer apt search foo | grep -v ^$
wvducky

15

Với sự giúp đỡ từ câu trả lời được chấp nhận ở đây và câu trả lời được chấp nhận ở trên, tôi đã sử dụng:

$ sed 's/^ *//; s/ *$//; /^$/d; /^\s*$/d' file.txt > output.txt

`s/^ *//`  => left trim
`s/ *$//`  => right trim
`/^$/d`    => remove empty line
`/^\s*$/d` => delete lines which may contain white space

Điều này bao gồm tất cả các cơ sở và hoạt động hoàn hảo cho nhu cầu của tôi. Kudos để áp phích ban đầu @Kent và @kev


5

Bạn có thể nói:

sed -n '/ / p' filename    #there is a space between '//'

.. có nghĩa là print all lines except the empty one(s)và im lặng
Timo

2

Bạn cũng có thể làm điều gì đó tương tự bằng cách sử dụng "grep":

egrep -v "^$" file.txt

2

Điều này làm việc trong awk là tốt.

awk '!/^$/' file
xxxxxx
yyyyyy
zzzzzz

2

Bạn rất có thể thấy hành vi không mong muốn vì tệp văn bản của bạn đã được tạo trên Windows, do đó, kết thúc chuỗi là \r\n. Bạn có thể sử dụng dos2unix để chuyển đổi nó thành tệp văn bản kiểu UNIX trước khi chạy sed hoặc sử dụng

sed -r "/^\r?$/d"

để loại bỏ các dòng trống cho dù có trở lại vận chuyển hay không.


Xin chào, -rcờ đang làm gì và có thể kết hợp nó với -iđể sửa đổi tệp trực tiếp và tránh in ra màn hình. Ngoài ra, tôi nghĩ rằng lệnh này cũng sẽ hoạt động nhưsed -r "/^\r$/d"
Alexander Cska

2

Một lựa chọn khác mà không sed, awk, perl, vv

strings $file > $output

chuỗi - in chuỗi ký tự có thể in trong tệp.


Bạn có nghĩa là stringsthay vì string?
Mickael B.

Xin chào @MickaelB. Bạn nói đúng, tôi sửa nó.
dùng319660

0

Câu bashtrả lời cụ thể của tôi là khuyên bạn nên sử dụng perltoán tử thay thế với gcờ mẫu chung cho việc này, như sau:

$ perl -pe s'/^\n|^[\ ]*\n//g' $file
xxxxxx
yyyyyy
zzzzzz

Câu trả lời này minh họa cho việc liệu các dòng trống có khoảng trắng trong chúng hay không [\ ]*, cũng như sử dụng| để phân tách nhiều thuật ngữ / trường tìm kiếm. Đã thử nghiệm trên macOS High Sierra và CentOS 6/7.

FYI, mã gốc của OP sed '/^$/d' $filechỉ hoạt động tốt trong bashTerminal trên macOS High Sierra và CentOS 6/7 Linux tại cụm siêu máy tính hiệu năng cao.


-3

Đối với tôi với FreeBSD 10.1 với sed chỉ hoạt động giải pháp này:

sed -e '/^[     ]*$/d' "testfile"

phía trong [] có không gian và biểu tượng tab.

tập tin kiểm tra có chứa:

fffffff next 1 tabline ffffffffffff

ffffffff next 1 Space line ffffffffffff

ffffffff empty 1 lines ffffffffffff

============ EOF =============
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.