Xóa các dòng trống bằng grep


164

Tôi đã thử grep -v '^$'trong Linux và nó không hoạt động. Tập tin này đến từ một hệ thống tập tin Windows.

Câu trả lời:


300

Hãy thử như sau:

grep -v -e '^$' foo.txt

Các -etùy chọn cho phép mô hình regex cho phù hợp.

Các trích dẫn duy nhất xung quanh ^$làm cho nó hoạt động cho Cshell. Các shell khác sẽ hài lòng với dấu ngoặc đơn hoặc dấu ngoặc kép.

CẬP NHẬT: Điều này đối với tôi đối với một tệp có dòng trống hoặc "tất cả khoảng trắng" (chẳng hạn như dòng cửa sổ có kết thúc dòng kiểu "\ r \ n"), trong khi ở trên chỉ xóa các tệp có dòng trống và kết thúc dòng kiểu unix:

grep -v -e '^[[:space:]]*$' foo.txt

Egrep đó sẽ chỉ hoạt động đối với các tệp có 0 hoặc 1 khoảng trắng trên dòng, không dành cho các tệp có 2 khoảng trống trở lên. Thay đổi ? đến *.
Ed Morton

4
Điều này nên grep -E -v, mọi thứ sau -eđược hiểu là mô hình.
jazzpi

6
grep -v -e '^[[:space:]]*$' -e '^#' filesẽ cung cấp cho bạn tất cả các dòng không trống, không bình luận trong tập lệnh hoặc tệp cấu hình (hoặc bất kỳ loại tệp nào sử dụng ký tự băm để nhận xét).
palswim

" -eTùy chọn cho phép các mẫu regex cho khớp." Điều đó rất sai lệch . -elà một định nghĩa (POSIX-) cho: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(từ hướng dẫn ). Grep đã mong đợi một biểu thức chính quy (cơ bản) theo mặc định. Đối với mẫu này, bạn có thể bỏ -ehoàn toàn : grep -v '^[[:space:]]*$' foo.txt.
Yeti

73

Giữ cho nó đơn giản.

grep . filename.txt

1
điều này mang lại cho tôi tất cả các dòng trong tệp
phuclv

2
@ LưuViênPhúc Cần xuất tất cả các dòng trong tệp ngoại trừ các dòng trống.
Frej Connolly

2
Điều này làm việc cho tôi trên các tệp từ hệ thống dựa trên linux nhưng không phải trên các tệp từ Windows. Có lẽ là do các ký tự kết thúc dòng Windows.

Tôi ủng hộ điều này mặc dù nó không giải quyết được vấn đề của OP khi xử lý một tệp có kết thúc dòng Windows, nhưng vì tôi không gặp phải vấn đề đó, nên đây hóa ra là giải pháp hoàn hảo cho tôi.
David Z

1
Đây là giải pháp hoàn hảo. Đơn giản và làm việc trên Linux.
W00f

30

Sử dụng:

$ dos2unix file
$ grep -v "^$" file

Hoặc chỉ đơn giản là awk:

awk 'NF' file

Nếu bạn không có dos2unix, thì bạn có thể sử dụng các công cụ như tr :

tr -d '\r' < "$file" > t ; mv t "$file"

Không thể tìm thấy chương trình dos2unix. Đó có phải là cho Windows? lệnh hỏi cũng không hoạt động.
nút ninja

hỏi? Không, đó là awk.
iconoclast

Điểm hay về việc chuyển đổi sang kết thúc dòng kiểu UNIX nếu không các biểu thức thông thường có thể không hoạt động như mong đợi. Không có gì ở đây làm việc cho tôi cho đến khi tôi chuyển đổi các kết thúc dòng.
Ryan H.

16
grep -v "^[[:space:]]*$"

The -v makes it print lines that do not completely match

===Each part explained===
^             match start of line
[[:space:]]   match whitespace- spaces, tabs, carriage returns, etc.
*             previous match (whitespace) may exist from 0 to infinite times
$             match end of line

Chạy mã-

$ echo "
> hello
>       
> ok" |
> grep -v "^[[:space:]]*$"
hello
ok

Để hiểu thêm về cách thức / lý do tại sao điều này hoạt động, tôi khuyên bạn nên đọc các biểu thức thông thường. http://www.THER-expressions.info/tutorial.html


2
Làm thế nào và tại sao điều này làm việc? Câu trả lời của bạn sẽ tốt hơn nhiều nếu bạn có thể giải thích. Chẳng hạn, biểu thức chính quy của bạn khớp với phần đầu của chuỗi sau đó một hoặc nhiều khoảng trắng bằng cách sử dụng tiêu chuẩn POSIX sau đó là phần cuối của chuỗi, tức là với grep -v, nó sẽ xóa tất cả các dòng chỉ là khoảng trắng. Đúng? Điều gì xảy ra nếu không có không gian; nó chỉ đơn giản là một nhân vật mới?
Bến

Như ví dụ của tôi cho thấy, thậm chí chỉ có một dòng trống bị xóa (dòng đầu tiên). Tôi đã thêm thông tin, vì vậy hy vọng rằng sẽ giúp. :)
Sepero

3

Tôi thích sử dụng egrep, mặc dù trong thử nghiệm của tôi với một tệp chính hãng với dòng trống, cách tiếp cận của bạn hoạt động tốt (mặc dù không có dấu ngoặc kép trong thử nghiệm của tôi). Điều này cũng làm việc:

egrep -v "^(\r?\n)?$" filename.txt

Đã thử mà. Dòng trống vẫn đang hiển thị. Điều này có thể là do các tập tin đã được thực hiện trong Windows?
nút ninja

3

Nếu bạn có chuỗi nhiều dòng trống liên tiếp và chỉ muốn một dòng trống trên mỗi chuỗi, hãy thử

grep -v "unwantedThing" foo.txt | cat -s

cat -s triệt tiêu các dòng đầu ra trống lặp đi lặp lại.

Đầu ra của bạn sẽ đi từ

match1



match2

đến

match1

match2

Ba dòng trống trong đầu ra ban đầu sẽ được nén hoặc "nén" thành một dòng trống.


2
awk 'NF' file-with-blank-lines > file-with-no-blank-lines

2

Giống như các câu trả lời trước:

grep -v -e '^$' foo.txt

Ở đây, grep -ecó nghĩa là phiên bản mở rộng của grep . '^ $' có nghĩa là không có bất kỳ ký tự nào giữa ^ (Bắt đầu dòng) và $ (cuối dòng). '^' và '$' là các ký tự regex.

Vì vậy, lệnh grep -vsẽ in tất cả các dòng không khớp với mẫu này (Không có ký tự nào giữa ^ và $).

Bằng cách này, các dòng trống rỗng được loại bỏ.


-ekhông có nghĩa là "phiên bản mở rộng của grep", có thể bạn đang nhầm lẫn với -E? Hướng dẫn rõ ràng nói rằng -echỉ cần nói rõ ràng rằng một mô hình sau. Vì mẫu không bắt đầu bằng dấu gạch ngang và dù sao bạn cũng chỉ xác định một mẫu, nên bạn cũng có thể loại bỏ nó vì theo mặc định, grep mong đợi một mẫu regex: grep -v '^$' foo.txt(không cần chức năng regex mở rộng). Ngoài ra, điều đáng nói là điều này không loại bỏ các dòng trống trong tệp, chỉ có điều được dẫn qua đầu ra. Đối với trường hợp đó, sed -isẽ là công cụ phù hợp.
Yeti

1

Tôi đã cố gắng hết sức, nhưng điều này có vẻ hiệu quả (giả sử \rđang cắn bạn ở đây):

printf "\r" | egrep -xv "[[:space:]]*"

Nó hoạt động nếu tôi thay thế phần đầu tiên bằng đầu ra từ tệp.
nút ninja

0

Sử dụng Perl:

perl -ne 'print if /\S/'

\S có nghĩa là khớp các ký tự không trống.


0

egrep -v "^ \ s \ s +"

egrep đã làm regex và \ s là khoảng trắng.

+ Nhân đôi mẫu hiện tại.

^ Là bắt đầu


0

Sử dụng:

grep pattern filename.txt | uniq

uniqsẽ giảm các dòng trống liền kề thành chỉ một dòng trống, nhưng không loại bỏ chúng hoàn toàn. Tuy nhiên, tôi thích cố gắng sử dụng uniqnhư vậy. Sắp xếp trước sẽ loại bỏ hiệu quả tất cả các dòng trống - chỉ để lại một dòng, nhưng sắp xếp lại thứ tự dòng có thể không được chấp nhận.
Zach Young

Điểm tốt. Điều này cũng sẽ chomp dòng lặp đi lặp lại. Tôi đoán giải pháp của tôi giới thiệu lỗi.
baitisj

0

Đây là một cách khác để loại bỏ các dòng trắng và dòng bắt đầu bằng #dấu hiệu. Tôi nghĩ rằng điều này là khá hữu ích để đọc các tập tin cấu hình.

[root@localhost ~]# cat /etc/sudoers | egrep -v '^(#|$)'
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS"
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
stack ALL=(ALL) NOPASSWD: ALL

0

Đúng là việc sử dụng grep -v -e '^ $' có thể hoạt động, tuy nhiên nó không xóa các dòng trống có 1 hoặc nhiều khoảng trắng trong đó . Tôi tìm thấy câu trả lời dễ nhất và đơn giản nhất để loại bỏ các dòng trống là việc sử dụng awk . Sau đây là một chút sửa đổi từ những người awk ở trên:

awk 'NF' foo.txt

Nhưng vì câu hỏi này là để sử dụng grep nên tôi sẽ trả lời như sau:

grep -v '^ *$' foo.txt

Lưu ý : khoảng trống giữa ^ và *.

Hoặc bạn có thể sử dụng \ s để thể hiện không gian trống như thế này:

grep -v '^\s*$' foo.txt
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.