Làm thế nào để in tất cả các cột sau một số cụ thể bằng awk?


Câu trả lời:


82
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

3
một vài cải tiến nhỏ:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman

Cảm ơn @glenn, đó thực sự là một chút tổng quát hơn. Dù sao - tôi chắc chắn đồng ý rằng tốt hơn là sử dụng cuthoặc perlcho việc này. Chỉ sử dụng điều này nếu bạn thực sự khăng khăng muốn có nó awk.
Amadan

1
@SiegeX: Nó không thêm NUL byte, nó để lại FS ở vị trí giữa mỗi trường trống.
Tạm dừng cho đến khi có thông báo mới.

1
Vui lòng xem câu trả lời của @ Ascherer để biết sự thanh lịch.

3
@veryhungrymike: Thanh lịch là tốt, nhưng tôi muốn đúng hơn. : p
Amadan

68

Khi bạn muốn thực hiện một loạt các lĩnh vực, awkthực sự không có cách nào để làm điều này. cutThay vào đó, tôi muốn giới thiệu :

cut -d' ' -f 9- ./infile

Biên tập

Đã thêm dấu phân cách trường dấu cách do mặc định là một tab. Cảm ơn Glenn đã chỉ ra điều này


15
Một điều về cut là nó sử dụng một dấu phân cách cụ thể (tab theo mặc định), trong đó awk sử dụng "khoảng trắng". Khi cắt, 2 tab liên tiếp sẽ phân tách một trường trống.
glenn jackman

1
Như @glennjackman đã chỉ ra, dấu phân cách của awk là "khoảng trắng" (bất kỳ số lượng nào). Vì vậy, đặt dấu phân cách cắt thành một khoảng trắng cũng sẽ không phù hợp với hành vi. Thật không may, vòng lặp là vòng lặp tốt nhất có thể làm, vì vậy nó có vẻ.
poncha

Cái này không hoạt động đúng. Hãy thử lệnh find . | xargs ls -l | cut -d' ' -f 9-. Vì lý do nào đó, khoảng trắng đôi cũng được tính. Ví dụ: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_bsẽ dẫn đến./file_a 00:06 ./file_b
Marco Pashkov

@MarcoPashkov xin hãy giải thích về một này không hoạt động đúng cách , đặc biệt là xem xét việc bạn sử dụng chính xác cùng một mã trong đường ống của bạn. Bằng cách này, bạn nên không bao giờ cố gắng để phân tích đầu ra của ls
SiegeX

cắt không làm công việc ở đây. Ví dụ: nếu đầu vào của bạn là "foo bar" (một khoảng trắng) cho một dòng và "foo ___ bar" (tức là nhiều khoảng trắng, nhưng SO quá thông minh để hiển thị nó) cho một dòng khác, việc cắt sẽ xử lý chúng theo cách khác.
UKMonkey

54
awk '{print substr($0, index($0,$9))}'

Chỉnh sửa : Lưu ý, điều này không hoạt động nếu bất kỳ trường nào trước trường thứ chín chứa cùng giá trị với trường thứ chín.


3
cái này là tuyệt vời!

10
@veryhungrymike: ... và không hoạt động nếu bất kỳ trường nào trước trường thứ chín chứa cùng giá trị với trường thứ chín.
Amadan

6
Có lẽ vì câu cổ điển "hy vọng tệp của bạn không có vấn đề đó". Đó là một kỹ thuật hoàn toàn không có trong s / w để tuyên bố: "chúng tôi sẽ không lãng phí thời gian bao gồm việc kiểm tra lỗi đầu vào của các giá trị âm, ví dụ: bởi vì chúng tôi hy vọng người dùng sẽ đủ thông minh để không thử chúng, làm hỏng công cụ của chúng tôi '". HAHAHA! Luôn thích nghe điều này! (Tôi thích khiếu hài hước) Chà, như những kẻ ngốc vẫn tồn tại, nhiệm vụ của nhà phát triển là làm cho những thứ của mình trở nên không thể ngu ngốc ! Thay vì "mong điều tốt lành ở con người". Đó là thay vì một thái độ mong đợi với các nhà triết học, không phải là / w kỹ sư ... LOL
Lỗi Cú pháp

3
Tôi không nói là không kiểm tra lỗi, nhưng nếu bạn biết mình sẽ không gặp phải vấn đề, thì giải pháp này là tốt, như tôi đã nêu. Nhưng cảm ơn bạn vì downvote @syntaxerror không cần thiết. Giải pháp này sẽ hoạt động đối với một số người, vì 19 phiếu ủng hộ (hiện tại) sẽ hiển thị, nhưng nếu không, thì đừng sử dụng nó cho giải pháp của bạn. Có rất nhiều cách để giải quyết vấn đề của OP.
Ascherer

1
Nếu bạn đang sử dụng awk trên dòng lệnh trong công việc hàng ngày thì đây chắc chắn là giải pháp mà bạn mong muốn. Nó không hiển nhiên? Kiểm tra lỗi, v.v., không thực sự quan trọng trong trường hợp đó vì bạn đang nhập nó vào và có thể gặp những thứ này trước khi bạn nhấn enter (cá nhân tôi, tôi không nghĩ awk nên được sử dụng cho bất kỳ thứ gì khác, đó là lý do tại sao chúng tôi 'đã có perl, python, tcl và hơn 100 ngôn ngữ viết lệnh khác, tốt hơn, nhanh hơn, ít gây phiền nhiễu hơn!)' Tất nhiên có lẽ tôi đang cho các nhà phát triển phần mềm đồng nghiệp của tôi quá nhiều tín dụng và họ thực sự cần kiểm tra lỗi ngay cả trên những thứ họ nhập đang bay (??)
osirisgothra

11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

Thay vì xử lý khoảng trắng có chiều rộng thay đổi, hãy thay thế tất cả khoảng trắng thành một khoảng trắng. Sau đó, sử dụng đơn giản cutvới các lĩnh vực quan tâm.

Nó không sử dụng awk vì vậy không phải là Đức nhưng có vẻ phù hợp với các câu trả lời / nhận xét khác.


1
Vui lòng làm cho câu trả lời của bạn kỹ lưỡng hơn, nếu không hãy đăng bài này dưới dạng nhận xét cho câu hỏi.
Alper Turan

Điều này là lý tưởng để ps faux | sử dụng. Đừng bao giờ sợ thừa nhận công cụ XYZ không phải là thích hợp nhất.
kevinf 23/02/16

10

Nói chung perl thay thế awk / sed / grep et. al., và nhiều hơn xách tay (cũng như chỉ là một con dao nhỏ càng tốt).

perl -lane 'print "@F[8..$#F]"'

Tất nhiên là áp dụng Timtowtdi.


Bạn cần thêm tùy chọn dòng lệnh -lhoặc thêm \nvào câu lệnh in.
glenn jackman

@glenn jackman: Có thể. Không bắt buộc nếu một phần của thông báo khác, hoặc được gán cho một biến, v.v. Theo như "tốt hơn", perl chắc chắn trông đẹp hơn trong phạm vi nhỏ. Phải thừa nhận là có thể trông rất bừa bộn.
bobbogo

Đừng hiểu lầm tôi, tôi thích Perl. Tôi yêu awk cho những gì nó là mặc dù.
glenn jackman

Thiết bị nhúng của tôi không đi kèm với Perl, nhưng nó có awk.
Sepero

Không đồng ý vì câu hỏi hỏi cách thực hiện điều này trong awk, không phải perl, ruby, java, python, bash.
Tom Harrison

3
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

Thao tác này cắt những gì ở trước trường đã cho nr., N và in tất cả phần còn lại của dòng, bao gồm trường nr.N và duy trì khoảng cách ban đầu (nó không định dạng lại). Nó không có giá trị nếu chuỗi của trường cũng xuất hiện ở một nơi khác trong dòng, đó là vấn đề với câu trả lời của Ascherer.

Xác định một chức năng:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

Và sử dụng nó như thế này:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

Đầu ra duy trì mọi thứ, bao gồm cả khoảng trắng ở cuối Đối với N = 0, nó trả về toàn bộ dòng, và đối với n> NF là chuỗi trống


Đây là một ý tưởng tốt. Nó không hoàn toàn hoạt động trên máy Mac hiện tại bằng cách sử dụng gawk thông thường, vì $ 0 bị sập. Cách khắc phục là đặt một biến thành $ 0 ở bước đầu tiên, chẳng hạn như: '{s = $ 0; ... in substr (s, chỉ số (s, m) +1}
joelparkerhenderson

1

Đây là một ví dụ về ls -lđầu ra:

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

Giải pháp của tôi để in bất cứ thứ gì đăng $9awk '{print substr($0, 61, 50)}'



0

Để hiển thị 3 trường đầu tiên và in các trường còn lại, bạn có thể sử dụng:

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

trong đó $ 1 $ 2 $ 3 là 3 trường đầu tiên.


0
function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

0

Sử dụng cut thay vì awk và khắc phục các vấn đề với việc tìm ra cột để bắt đầu bằng cách sử dụng lệnh cắt ký tự -c.

Ở đây tôi đang nói, cung cấp cho tôi tất cả ngoại trừ 49 ký tự đầu tiên của đầu ra.

 ls -l /some/path/*/* | cut -c 50-

/*/*/cuối lệnh ls cũng nói cho tôi biết những gì có trong thư mục con.

Bạn cũng có thể lấy ra một số phạm vi ký tự nhất định (từ trang người đàn ông đã cắt). Ví dụ: hiển thị tên và thời gian đăng nhập của những người dùng hiện đang đăng nhập:

       who | cut -c 1-16,26-38
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.