In cột / trường cuối cùng thứ hai trong awk


164

Tôi muốn in cột hoặc trường cuối cùng thứ hai trong awk. Số lượng các lĩnh vực là biến. Tôi biết rằng tôi sẽ có thể sử dụng $NFnhưng không chắc làm thế nào nó có thể được sử dụng.

Và điều này dường như không hoạt động:

awk ' { print ( $NF-- )  } '

10
NFlà chỉ số trường cuối cùng, $NFlà giá trị của trường cuối cùng
glenn jackman

Điều đó có ý nghĩa bây giờ. đó là lý do tại sao đồng đô la bên ngoài dấu ngoặc đơn hoạt động tôi cho rằng
Brian G

Câu trả lời:


279
awk '{print $(NF-1)}'

Nên làm việc


2
Điều này không làm việc cho tôi. Tôi nhận được "title: 5: lệnh không tìm thấy: NF-1" trong awk 3.1.8 trong Ubuntu.
Gurgeh

3
Tôi sẽ tránh việc giảm trước / sau để đảm bảo bạn không thay đổi giá trị của $ NF
Gregory Patmore

Điều này sẽ phá vỡ nếu bạn cố gắng có được trường thứ ba cuối cùng nhưawk -F '.' '{print $(NF-2)}'
gies0r

3
@Gurgeh: Điều này xảy ra vì $(..)gọi một lệnh trong một lớp con tùy thuộc vào lớp vỏ bạn đang sử dụng. Bạn có thể làm việc xung quanh điều này bằng cách sử dụng $ (NF-1)thay vì $(NF-1).
wting

21

Bổ sung nhỏ vào câu trả lời được chấp nhận của Chris Kannon: chỉ in nếu thực sự có cột thứ hai cuối cùng.

(
echo       | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1     | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2   | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)

15

Nó đơn giản nhất:

 awk '{print $--NF}' 

Lý do ban đầu $NF--không hoạt động là vì biểu thức được đánh giá trước khi giảm, trong khi việc giảm tiền tố của tôi được thực hiện trước khi đánh giá.


Như một ghi nhớ, hành vi này giống như C / Java int x = ++i int x = i++, v.v. , tiền tố có nghĩa là tăng trước; postfix có nghĩa là tăng sau (gán trước).
Cuối tuần


4

Bạn không xa kết quả! Cái này làm được

awk '{NF--; print $NF}' file

Điều này làm giảm số lượng các trường trong một, do đó $NFcó chứa áp chót trước đây.

Kiểm tra

Hãy tạo một số số và in chúng trên các nhóm 5:

$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12

Hãy in áp chót trên mỗi dòng:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11

3

Giải pháp Perl tương tự như giải pháp awk của Chris Kannon:

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

Các tùy chọn dòng lệnh này được sử dụng:

  • n lặp xung quanh mỗi dòng của tệp đầu vào, không tự động in mọi dòng

  • l xóa các dòng mới trước khi xử lý và thêm chúng trở lại sau đó

  • achế độ tự động - chia dòng đầu vào thành @Fmảng. Mặc định để phân tách trên khoảng trắng

  • e thực thi mã perl

Các @Fmảng autosplit giá khởi điểm chỉ số [0] trong khi lĩnh vực awk bắt đầu với $ 1.
$#Flà số phần tử trong@F


1
hoặc sử dụng lập chỉ mục tiêu cực đã được cung cấp bởi perl ...$F[-2]
Sundeep

2

Bạn đã thử bắt đầu từ phải sang trái bằng cách sử dụng lệnh rev? Trong trường hợp này, bạn chỉ cần in cột thứ 2:

seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11

1

Đầu tiên giảm giá trị và sau đó in nó -

awk ' { print $(--NF)}' file

HOẶC LÀ

rev file|cut -d ' ' -f2|rev

0

Nếu bạn có nhiều cột và muốn in tất cả nhưng không phải là ba cột cuối cùng, thì điều này có thể giúp

awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'

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.