Hiển thị dòng trống bằng lệnh cat


11

Tôi có một danh sách files.txt, bên dưới:

-rw-rw-r-- 1 root dev 11 May 16 12:18 20_SumActive.txt  
-rw-rw-r-- 1 root dev 11 May 16 12:18 22_SumActive.txt  
-rw-rw-r-- 1 root dev  7 May 16 12:18 24_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 26_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 28_SumActive.txt  

Đầu ra:

kpgmeddev01> cat 2[0-8]_SumActive.txt   
Sum: 47760  
Sum: 72000  
Sum: 0

Cách lấy đầu ra như sau:

Sum: 47760  
Sum: 72000  
Sum: 0  
[Blank]  
[Blank]  

Cần hướng dẫn.


Các tập tin có bao giờ chứa nhiều hơn một dòng không?
roaima

Không, chỉ có 1 dòng
Fewong

1
Uh, khi bạn viết [Blank]bạn có nghĩa là 7 ký tự đó hay bạn có ý định chỉ ra một dòng trống?
roaima

1
Bằng cách không sử dụng mèo. Đừng kiềm chế bản thân.
ctrl-alt-delor

Câu trả lời:


20

catkhông thể xuất dữ liệu không tồn tại trong các tập tin. Nếu một tệp trống, nó thậm chí không có ký tự dòng mới để cung cấp một dòng trống làm đầu ra.

Bạn có thể đảm bảo rằng các tệp chứa ít nhất một ký tự dòng mới.

Đây là cách bạn sử dụng GNU awkđể đảm bảo rằng (điều này sửa đổi các tệp trống):

awk 'ENDFILE { if (FNR == 0) printf("\n") >>FILENAME }' 2[0-8]_SumActive.txt   

Các ENDFILEkhối sẽ được thực hiện sau khi kết thúc đọc bất kỳ của các tập tin. Nếu FNRbằng 0, chúng tôi không bao giờ thấy bất kỳ dòng nào trong tệp, vì vậy chúng tôi chèn một dòng mới vào nó. Kịch bản sau đó tiếp tục với tập tin tiếp theo.

Sau đó bạn có thể sử dụng catnhư bạn đã làm trong câu hỏi.


Ngoài ra, không thay đổi các tệp, sử dụng GNU awk thay vì cat :

awk 'ENDFILE { if (FNR == 0) printf("\n") } 1' 2[0-8]_SumActive.txt

Điều này thực hiện cùng loại phát hiện các tệp trống như trên, nhưng in dòng mới thành đầu ra tiêu chuẩn chứ không phải cho tệp. Các 1cuối cùng có thể được thay thế bằng { print }và sẽ gây ra tất cả dữ liệu trong các tập tin không bị trống để được outputted.


Ngoài ra, một vòng lặp shell (nên hoạt động trong bất kỳ shell POSIX nào):

for name in ./2[0-8]_SumActive.txt; do
    if [ -s "$name" ]; then
        cat "$name"
    else
        printf '\n'
    fi
done

Các -sthử nghiệm sẽ được true nếu tập tin tồn tại và có một lớn hơn kích thước hơn không.


Nếu bạn muốn chuỗi ký tự [Blank]được xuất ra cho các tệp trống, chỉ cần chèn chuỗi đó ở phía trước \ntrong các lệnh gọi printfở trên (điều này cũng sẽ hoạt động trong awkmã).


2
@Fewong Tốt! Nếu điều này giải quyết vấn đề của bạn, xin vui lòng xem xét chấp nhận câu trả lời .
Kusalananda

@Fewong: Hoặc chấp nhận một câu trả lời khác giúp bạn tốt hơn - đó là một cách tốt để tạo cơ hội cho mọi múi giờ, vì vậy đừng vội vàng.
MSalters

@Fewong Chắc chắn không vội. Stephané cũng đã viết một giải pháp ngắn và gọn, có vẻ đầy hứa hẹn.
Kusalananda

@Kusalananda, cảm ơn và tôi đã thử nó.
Fewong

16

Với perl

perl -0777 -pe 's/\n?\z/\n/' 2[0-8]_SumActive.txt

Việc thêm một ký tự dòng mới nếu thiếu ở cuối, do đó sẽ tạo ra một dòng trống cho các tệp trống, nhưng cũng sẽ thêm một dòng mới cho các tệp không trống mà bỏ lỡ các tệp (và cuối cùng sẽ được nối trên một dòng với cat).


gợi ý hay
erTugRul

13

(Đây không phải là chính xác những gì bạn yêu cầu, nhưng :) Trong loại tình huống này tôi thích sử dụng head

$ head -z 2[0-8]_SumActive.txt
==> 21_SumActive.txt <==
Sum: 47760  
Sum: 72000  
Sum: 0  

==> 22_SumActive.txt <==

==> 25_SumActive.txt <==

==> 28_SumActive.txt <==

Thông thường đây là những gì bạn muốn. Nếu không nó rất dễ dàng để sednó sau này


12

Với xargsgrepbạn có thể thử một cái gì đó như:

$>ls | xargs -n1 sh -c 'grep "" $0 || echo "[Blank]"'
Sum: 47760
Sum: 72000
Sum: 0
[Blank]
[Blank]

4
Có lẽ không phải là giải pháp nhanh nhất (tách vỏ cho mỗi tệp), nhưng chỉ có một giải pháp thực sự sẽ hoạt động nếu bạn có hàng triệu tệp như vậy trong thư mục hiện tại (không sử dụng mở rộng vỏ và đạt giới hạn ARGV).
Matija Nalis

1
@MatijaNalis: Rất đúng! Nhưng bạn thực sự sẽ không quan tâm đến 5 tập tin.
FloHimelf

6

Giả sử rằng [Blank]bạn có nghĩa là dòng trống theo nghĩa đen, điều này sẽ hoạt động:

paste -s 2[0-8]_SumActive.txt

6

Bạn có thể kiểm tra từng tệp để xem nó có độ dài bằng không trước khi thử hiển thị nội dung của nó:

for f in 2[0-8]_SumActive.txt;
do
    [[ -s "$f" ]] && awk 1 "$f" || echo '[Blank]'
done

Tôi đã sử dụng awk 1 "$f"thay cat "$f"vì vì awkđảm bảo kết thúc đầu ra của tệp bằng một dòng mới.

Trong câu hỏi của bạn, nếu bạn dự định [blank]không nên là một chữ, mà chỉ là một dòng trống, bạn có thể thực hiện điều này bằng cách sử dụng mã ở trên và xóa '[Blank]'khỏi cuối echocâu lệnh.


5

Tôi giả sử các tệp của bạn 26_SumActive.txt và 28_SumActive.txt trống và bạn cần các dòng trống khi hiển thị nội dung của chúng

Đối với điều này, bạn chỉ có thể lặp qua danh sách các tệp của mình và gửi nội dung của chúng và nếu tệp trống, lặp lại dòng trống.

[ -s FILE ] Đúng nếu FILE tồn tại và có kích thước lớn hơn 0.

$ for i in $(ls 2[0-8]_SumActive.txt) ; do  cat $i;  if [ ! -s $i ]; then echo -e ""; fi; done
Sum: 47760  
Sum: 72000  
Sum: 0  
[ Blank Line]
[ Blank Line ]

1
Hoặc if [ -s $i ]; then cat $i; else echo -e ""; fi;. Vẫn +1 cho một thử nghiệm đơn giản chỉ sử dụng chức năng vỏ tiêu chuẩn.
MSalters

2
Hoặc chỉ cat "$i"; test -s "$i" || echo- không cần cho ifcác echocờ khó sử dụng hoặc không di động .
Toby Speight

1
cat 2[0-8]_SumActive.txt -

trong đó - sẽ cho phép mèo đọc từ đầu vào tiêu chuẩn.

Vì vậy, sau khi hiển thị nội dung các tập tin của bạn, mèo sẽ đợi đầu vào của bạn. Bạn có thể thực hiện đầu vào mong muốn của mình, bằng cách nhấn enter cho khoảng trống theo nghĩa đen hoặc [Trống] nếu đó là những gì bạn muốn. Sau mỗi lần nhấn enter, một khi tất cả đầu vào được thực hiện, nhấn ^ D (Ctrl + D) và bạn đã hoàn tất.

PS: Đối với mỗi đầu vào, bạn sẽ nhận được đầu ra tương ứng.

cat 2[0-8]_SumActive.txt - 4[0-8]_SumActive.txt

Với điều này, bạn có thể đặt khoảng trống hoặc một cái gì đó bạn muốn, giữa hai chuỗi thông số.


Trên cơ sở này, bạn cũng có thể chỉ cung cấp catnhư một giải pháp và cho phép OP thực hiện những gì họ muốn.
roaima
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.