it-swarm-vi.com

sắp xếp nhưng giữ dòng tiêu đề ở trên cùng

Tôi đang nhận đầu ra từ một chương trình đầu tiên tạo ra một dòng là một loạt các tiêu đề cột và sau đó là một loạt các dòng dữ liệu. Tôi muốn cắt các cột khác nhau của đầu ra này và xem nó được sắp xếp theo các cột khác nhau. Không có các tiêu đề, việc cắt và sắp xếp dễ dàng được thực hiện thông qua -k tùy chọn để sort cùng với cut hoặc awk để xem tập hợp con của các cột. Tuy nhiên, phương pháp sắp xếp này trộn các tiêu đề cột với phần còn lại của các dòng đầu ra. Có một cách dễ dàng để giữ các tiêu đề ở đầu?

63
jonderry

Ăn cắp ý tưởng của Andy và biến nó thành một chức năng để dễ sử dụng hơn:

# print the header (the first line of input)
# and then run the specified command on the body (the rest of the input)
# use it in a pipeline, e.g. ps | body grep somepattern
body() {
    IFS= read -r header
    printf '%s\n' "$header"
    "[email protected]"
}

Bây giờ tôi có thể làm:

$ ps -o pid,comm | body sort -k2
  PID COMMAND
24759 bash
31276 bash
31032 less
31177 less
31020 man
31167 man
...

$ ps -o pid,comm | body grep less
  PID COMMAND
31032 less
31177 less
66
Mikel

Bạn có thể giữ tiêu đề ở đầu như thế này với bash:

command | (read -r; printf "%s\n" "$REPLY"; sort)

Hoặc làm điều đó với Perl:

command | Perl -e 'print scalar (<>); print sort { ... } <>'
41
Andy

Tôi đã tìm thấy một phiên bản awk Nice hoạt động độc đáo trong các tập lệnh:

awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'
30
Michael Kuhn

Hackish nhưng hiệu quả: trả trước 0 cho tất cả các dòng tiêu đề và 1 cho tất cả các dòng khác trước khi sắp xếp. Dải tiền tố sau khi sắp xếp.

… |
awk '{print (NR <= 2 ? "0 " : "1 ") $0}' |
sort -k 1 -k… |
cut -b 3-

Dưới đây là một số tiếng ồn dòng Perl kỳ diệu mà bạn có thể dẫn đầu ra của mình để sắp xếp mọi thứ nhưng vẫn giữ dòng đầu tiên ở trên cùng: Perl -e 'print scalar <>, sort <>;'

4
Ryan C. Thompson

Tôi đã thử command | {head -1; sort; } giải pháp và có thể xác nhận rằng nó thực sự làm hỏng mọi thứ --head đọc nhiều dòng từ ống, sau đó chỉ xuất ra dòng đầu tiên. Vì vậy, phần còn lại của đầu ra, mà head đã không đọc, được chuyển đến sort-- KHÔNG phải phần còn lại của đầu ra bắt đầu từ dòng 2!

Kết quả là bạn bị thiếu các dòng (và một dòng một phần!) Ở đầu đầu ra lệnh của bạn (ngoại trừ bạn vẫn có dòng đầu tiên) - một thực tế rất dễ xác nhận bằng cách thêm một đường ống vào wc ở cuối đường ống trên - nhưng điều đó cực kỳ khó truy tìm nếu bạn không biết điều này! Tôi đã dành ít nhất 20 phút để cố gắng tìm ra lý do tại sao tôi có một dòng một phần (100 byte đầu tiên hoặc lâu hơn bị cắt) trong đầu ra của tôi trước khi giải quyết nó.

Điều cuối cùng tôi đã làm, hoạt động rất hay và không yêu cầu chạy lệnh hai lần, là:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile
sed 1d $myfile | sort

rm $myfile

Nếu bạn cần đặt đầu ra vào một tệp, bạn có thể sửa đổi điều này thành:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile > outputfile
sed 1d $myfile | sort >> outputfile

rm $myfile
2
Wildcard

Tôi nghĩ rằng điều này là dễ dàng nhất.

ps -ef | ( head -n 1 ; sort )

hoặc cái này có thể nhanh hơn vì nó không tạo ra một Shell phụ

ps -ef | { head -n 1 ; sort ; }

Công dụng tuyệt vời khác

xáo trộn dòng sau hàng tiêu đề

cat file.txt |  ( head -n 1 ; shuf )

dòng ngược sau hàng tiêu đề

cat file.txt |  ( head -n 1 ; tac )
1
user2449151
command | head -1; command | tail -n +2 | sort
0
Sarva

Tôi đến đây để tìm giải pháp cho lệnh w. Lệnh này hiển thị chi tiết về người đã đăng nhập và những gì họ đang làm.

Để hiển thị kết quả được sắp xếp, nhưng với các tiêu đề được giữ ở trên cùng (có 2 dòng tiêu đề), tôi đã giải quyết:

w | head -n 2; w | tail -n +3 | sort

Rõ ràng điều này chạy lệnh w hai lần và do đó có thể không phù hợp với mọi tình huống. Tuy nhiên, với lợi thế của nó, nó dễ nhớ hơn nhiều.

Lưu ý rằng tail -n +3 có nghĩa là 'hiển thị tất cả các dòng từ thứ 3 trở đi' (xem man tail để biết chi tiết).

0
Robert

Đơn giản và dễ hiểu!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd ---> 'n' chỉ định dòng số. và 'd' là viết tắt của xóa.
0
Jatsui