Trên shell, tôi chuyển sang awk khi tôi cần một cột cụ thể.
Điều này in ra cột 9, ví dụ:
... | awk '{print $9}'
Làm cách nào để yêu cầu awk in tất cả các cột bao gồm và sau cột 9 , không chỉ cột 9?
Câu trả lời:
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'
awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
cut
hoặc perl
cho 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
.
Khi bạn muốn thực hiện một loạt các lĩnh vực, awk
thực sự không có cách nào để làm điều này. cut
Thay vào đó, tôi muốn giới thiệu :
cut -d' ' -f 9- ./infile
Đã 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
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_b
sẽ dẫn đến./file_a 00:06 ./file_b
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.
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 cut
vớ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.
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.
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.
-l
hoặc thêm \n
vào câu lệnh in.
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 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 $9
làawk '{print substr($0, 61, 50)}'
Để 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.
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