Làm cách nào để sử dụng cắt để phân tách bằng nhiều khoảng trắng?


23

Tôi muốn lấy cột cuối cùng của mẫu này:

[  3]  1.0- 2.0 sec  1.00 MBytes  8.39 Mbits/sec
[  3]  2.0- 3.0 sec   768 KBytes  6.29 Mbits/sec
[  3]  3.0- 4.0 sec   512 KBytes  4.19 Mbits/sec
[  3]  4.0- 5.0 sec   256 KBytes  2.10 Mbits/sec
...

Nếu tôi sử dụng

cut -d\  -f 13

tôi có

Mbits/sec
6.29
4.19
2.10

bởi vì đôi khi có thêm không gian ở giữa.


Cột cuối cùng là Mbits/sec, đó là những gì bạn muốn hoặc 2 cột cuối cùng?
terdon

1
Tôi chỉ muốn lấy cột thứ 2 cuối cùng, chỉ các số
rubo77

Câu trả lời:


17

Để trả lời câu hỏi của bạn theo nghĩa đen:

sed 's/   */:/g' | cut -d : -f 5

hoặc là

awk -F '  +' '{print $5}'

Nhưng điều đó sẽ không xảy ra nếu số trong ngoặc đạt 10, v.v. Nếu bạn chỉ quan tâm đến các số, bạn có thể xóa mọi thứ khác.

sed 's/[^.0-9][^.0-9]*/:/g' | cut -d : -f 6

có, chỉ chắc chắn các con số, nhưng chỉ ví dụ thứ 3 của bạn hoạt động chính xác
rubo77

@ rubo77 Hoạt động cho tôi. Hai ví dụ đầu tiên làm chính xác những gì bạn yêu cầu trong tiêu đề của bạn. Hay bạn cũng muốn lột bỏ đơn vị? Trong trường hợp đó, thêm | sed 's/ .*//'vào cuối của hai ví dụ đầu tiên. Tất nhiên có nhiều cách khác để làm điều đó.
Gilles 'SO- ngừng trở nên xấu xa'

ngắn hơn một chút với +thay vì *: kiểm tra mèo | sed 's / [^. 0-9] \ + /: / g' | cắt -d: -f 6
rubo77

@ rubo77 Nếu sed của bạn hỗ trợ nó, đó là. Nó được GNU và BusyBox hỗ trợ nhưng không phải bằng BSD hoặc Solaris. POSIX chỉ định +?trong ERE nhưng lá \+\?trong BRE không xác định.
Gilles 'SO- ngừng trở nên xấu xa'

22

Nếu chúng ta sử dụng trlệnh cùng với tùy chọn bóp ( -scờ) để chuyển đổi tất cả nhiều khoảng trắng liên tiếp thành một khoảng trắng và sau đó thực hiện cutthao tác với khoảng trắng dưới dạng dấu phân cách - chúng ta có thể truy cập vào cột cần thiết mang các số.

Tham khảo đoạn mã dưới đây:

cat file | tr -s ' ' | cut -d ' ' -f 8


4
Câu trả lời này nên cao hơn; đó là bởi đến nay các giải pháp đơn giản nhất và dễ đọc nhất.
Luke Davis

5

Tất cả các lệnh này sẽ in cột cuối cùng của tệp được phân tách bằng dấu cách:

  • awk '{print $NF}' file

    trong awk, NFlà số lượng các trường và $NFlà trường cuối cùng.

  • perl -lane 'print $F[$#F]' file

    -achia tập tin trên khoảng trắng thành mảng @F, $#Flà số phần tử trong mảng vì vậy $F[$#F]là phần tử cuối cùng. Có -nnghĩa là đọc tệp được cung cấp trên dòng lệnh và áp dụng tập lệnh được truyền -echo mỗi dòng. -lchỉ cần thêm một ký tự dòng mới ( \n) vào mỗi printcâu lệnh.

  • sed 's/.* //g'

    một biểu thức chính quy đơn giản khớp mọi thứ với khoảng trắng cuối cùng và xóa nó, chỉ để lại cột cuối cùng.

  • rev file | cut -d' ' -f 1 | rev

    revđảo ngược đầu ra của nó để trường cuối cùng là trường đầu tiên, cutvới không gian dấu phân cách để in nó và revđảo ngược văn bản trở lại bình thường. Điều này sẽ không hoạt động nếu bạn có khoảng trắng liên tiếp .

Dựa trên đầu vào của bạn, tôi đoán bạn không thực sự muốn cột cuối cùng mà là áp chót một hoặc hai cột cuối cùng. Trong trường hợp đó, hãy sử dụng chúng để in 2 ( 8.39 Mbits/sec):

awk '{print $(NF-1),$NF}' file 
perl -lane 'print "$F[$#F-1] $F[$#F]"' file 
sed 's/.* \(.* .*\)/\1/' file 
rev file | cut -d' ' -f 1,2 | rev

và những thứ này để in áp chót ( 8.39):

awk '{print $(NF-1)}' file 
perl -lane 'print $F[$#F-1]' file 
sed 's/.* \(.*\) .*/\1/' file 
rev file | cut -d' ' -f 2 | rev

4

Bạn không thể phân tách nhiều lần xuất hiện của khoảng trắng bằng cách sử dụng cuttheo hướng dẫn:

Các trường đầu ra được phân tách bằng một lần xuất hiện của ký tự phân cách trường.

trừ khi văn bản được phân tách bằng cùng một lượng hoặc bạn sử dụng trđể loại bỏ chúng.

Nếu không, sử dụng các công cụ thay thế như awk, sedhoặc ex.

Ví dụ:

ex -s +'%norm $2Bd0' +%p +q! foo.txt

Thay thế +q!bằng -cwqđể lưu các thay đổi tại chỗ.


0

Sử dụng một lớp lót perl như vậy:

perl -lane 'print $F[-2]' input_file

Giải trình:

Tùy chọn -elàm cho trình thông dịch perl tìm kiếm tập lệnh nội tuyến, thay vì trong một tệp.

Tùy chọn -nlàm cho đầu vào (tệp hoặc STDIN từ một đường ống) được đọc từng dòng.

Tùy chọn -lloại bỏ dấu tách bản ghi đầu vào (phụ thuộc vào hệ điều hành, dòng mới trên UNIX theo mặc định) sau khi đọc dòng và thêm nó vào cuối cho mỗiprint

Tùy chọn -alàm cho mỗi dòng đầu vào được phân chia trên khoảng trắng thành mảng @F$F[-2]là phần tử thứ hai tính từ cuối, là trường bạn muốn. Bạn cũng có thể sử dụng $F[$#F-1], đâu $#Flà chỉ mục cuối cùng của mảng @F, ít đọc hơn một chút.

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.