Buộc các dòng mới với in mèo ký tự


9

Tôi muốn sử dụng cat với các ký tự đại diện trong bash để in nhiều tệp nhỏ (mỗi tệp là một câu) thành đầu ra tiêu chuẩn. Tuy nhiên, nội dung tệp riêng biệt không được phân tách bằng một dòng mới, mà tôi muốn đọc cho dễ đọc.

Làm thế nào tôi có thể thêm một dấu phân cách tệp của một số loại vào lệnh này?

Câu trả lời:


12

Xác định hàm shell xuất ra một dòng cuối sau mỗi tệp và sử dụng nó thay vì cat:

endlcat() {
  for file in "$@"; do
    cat -- "$file"
    echo
  done
}

sau đó bạn có thể sử dụng endlcat *.

Các forvòng lặp trên tất cả các đối số được cung cấp ( $@) đã được thoát khỏi trình bao khi bạn sử dụng các ký tự đại diện như thế nào *. Các --yêu cầu để không bị nghẹt thở trên tên tập tin bắt đầu với một dấu gạch ngang. Cuối cùng, echođầu ra một dòng mới.


Có vẻ khá rõ ràng để sử dụng lặp đi lặp lại trong nhận thức muộn màng! Tôi nghĩ rằng có thể có một lá cờ ở mèo, nhưng điều này cũng hoạt động! Cảm ơn bạn.
lennyklb

Bạn không cần in "$@"- nó ngầm.
l0b0

4
rõ ràng là tốt cho khả năng đọc.
cas

5

Chỉ cần sử dụng một vòng lặp thay vì đơn giản cat:

for file in /path/to/targetdir/*; do
    echo "-------- $file -------"
    cat "$file" 
done

Hoạt động như câu trả lời được chấp nhận, nhưng câu đó cũng có bước tiếp theo với dòng lệnh nên tôi đã chấp nhận câu trả lời khác.
lennyklb

3

Nếu bạn muốn tên tệp giữa các tệp, sử dụng tail:

tail -n +1 ./*

(Trong trường hợp bạn muốn tacthay vì cat, một số tailtriển khai có -rtùy chọn cho tacchức năng tương đương )


3

Điều này sẽ làm việc:

sed '' -- *

Bạn không cần bất kỳ vòng lặp shell nào khác, và điều này sẽ luôn theo đầu ra của một tệp với một \newline - ngoại trừ có lẽ là cuối cùng.

Mặt khác, nếu bạn muốn một dòng trống là đầu ra giữa đầu ra của mỗi tệp, điều này có thể hoạt động:

bpaste(){
    eval "paste -'sd\n' -- $(x=0;for f do printf "\"\${$((x+=1))}\" - ";done)"
}   </dev/null

Điều đó sẽ luôn theo đầu ra của một tệp với một \newline một dòng trống bổ sung .

Bạn có thể gọi nó như:

bpaste *

@cuonglm - op muốn một dòng mới giữa các tập tin. điều này đảm bảo một dòng mới giữa các tập tin.
mikeerv

@cuonglm - bạn nên thử lại. for n in 1 2 3; do printf "$n" >"$n"; done; sed '' -- [123]
mikeerv

@cuonglm - bất kỳ sedphải luôn luôn in một \newline trước khi nó in bất cứ điều gì khác, dòng cuối cùng của tệp cuối cùng có thể không nhận được một \newline được nối thêm. tôi có thể thề rằng tôi đã trả lời câu hỏi này trước đây.
mikeerv

@cuonglm - tôi không hiểu ý bạn. cái vỏ nhỏ đó tôi vừa cho bạn in 1\n2\n3. nó hoạt động nó luôn luôn như vậy. nó in cái gì cho bạn
mikeerv

1
@DennisWilliamson: Sử dụng \ntrong RHS không phải là tiêu chuẩn. Bạn có thể sử dụng sed -e '$G'.
cuonglm

2

Tương tự như câu trả lời của @terdon , nếu bạn cũng thích nhìn thấy tên tệp trong tương lai, bạn có thể sử dụng headlệnh:

$ head *file*
==> file_1 <==
file 1 content

==> file_2 <==
file 2 content

==> file_3 <==
file 3 content

headmặc định cho 10 dòng đầu tiên, vì vậy sử dụng nó mà không có tùy chọn lệnh cho trường hợp của bạn (một câu cho mỗi tệp) là hoàn toàn tốt. Nếu không, bạn cần -n Xtùy chọn.


2

Một cách khác - sử dụng grep -hđể chỉ cần tìm kiếm chuỗi trống trong mỗi tệp. Điều này sẽ phù hợp với tất cả các dòng, bất kể có bao nhiêu hoặc kết thúc dòng mới hay không. kết quả grep luôn được kết thúc dòng mới. Các -hngăn chặn tùy chọn tiền tố mỗi dòng đầu ra với tên tập tin nó đến từ:

$ printf 'a' > a
$ printf 'b\nB' > b
$ printf 'c\n' > c
$ ls
a  b  c
$ cat -- *
ab
Bc
$ grep -h '' *
a
b
B
c
$ 

Hoặc bạn có thể sử dụng GNU paste-schế độ erial với dòng mới làm dấu phân cách:

$ paste -s -d '\n' -- *
a
b
B
c
$ 
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.