Làm thế nào để sử dụng tôn giáo: phân tách trường awk?


Câu trả lời:


382

"-F" là một đối số dòng lệnh không phải cú pháp awk, hãy thử:

 echo "1: " | awk -F  ":" '/1/ {print $1}'

42
Câu hỏi dốt nát ở đây: / 1 / phần là để nói với awk chỉ xử lý các hàng (hoặc bản ghi chính xác hơn) có chứa số 1 phải không?
rantsh

3
@rantsh Cú pháp Awk trông như thế (pattern){action}. Nếu pattern(chủ yếu là một tuyên bố có điều kiện) là đúng , actionđược thực thi. Nếu patternkhông có sẵn, trueđược ngụ ý. Đây pattern/1/trạng thái mà regex 1khớp trong hồ sơ hiện tại$0
kaugeour

62

Nếu bạn muốn làm điều đó theo chương trình, bạn có thể sử dụng FSbiến:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Lưu ý rằng nếu bạn thay đổi nó trong vòng lặp chính thay vì BEGINvòng lặp, nó sẽ ảnh hưởng đến dòng tiếp theo được đọc, vì dòng hiện tại đã được tách.


35

Bạn có nhiều cách để đặt :làm dấu phân cách:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Tất cả chúng đều tương đương và sẽ trả về 1một đầu vào mẫu "1: 2: 3":

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1

cách ưa thích là gì? tôi giả sử ví dụ cuối cùng với BEGINtuyên bố sẽ là chính xác nhất (phù hợp với awkcú pháp tổng thể ).

1
@randomware tất cả đều ổn. Tôi có xu hướng sử dụng BEGINnếu tôi sử dụng một tập tin để lưu trữ toàn bộ, trong khi -Fcó ích với một lớp lót.
fedorqui 'SO ngừng làm hại'

1
Phải nói rằng có sự khác biệt tinh tế giữa trường hợp thứ ba và tất cả những người khác. Ví dụ: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kaugeour


12

-Flà một đối số cho awkchính nó:

$echo "1: " | awk -F":" '/1/ {print $1}'
1

2
Không cần trích dẫn đại tràng.
ceving

6

Bạn cũng có thể sử dụng biểu thức chính quy làm dấu tách trường, phần sau sẽ in "thanh" bằng cách sử dụng biểu thức chính quy để đặt số "10" làm dấu phân cách.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'

4

Không cần phải viết nhiều như vậy. Chỉ cần đặt dấu tách trường mong muốn của bạn với tùy chọn -F trong lệnh awk và số cột bạn muốn in tách riêng theo phân cách trường được đề cập của bạn.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1

4

AWK hoạt động như trình thông dịch văn bản đi theo chiều dọc cho toàn bộ tài liệuđi theo từng trường cho từng dòng, do đó $ 1, $ 2 .. $ n là các tham chiếu đến các trường của mỗi dòng ($ 1 là trường đầu tiên, $ 2 là trường thứ hai, v.v. ...). Bạn có thể xác định dấu tách trường bằng cách sử dụng công tắc "-F" bên dưới dòng lệnh hoặc trong hai dấu ngoặc với "FS = ...". Bây giờ hãy xem xét câu trả lời của "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

Phía trên các ranh giới trường được đặt bởi ":" vì vậy chúng tôi có hai trường $ 1 là "1" và $ 2 là khoảng trống. Sau đó, xuất hiện biểu thức chính quy "/ 1 /" chỉ cho bộ lọc chỉ xuất ra trường đầu tiên khi trình thông dịch tình cờ phát hiện ra một dòng chứa biểu thức như vậy (ý tôi là 1); Đầu ra của lệnh "echo" là một dòng chứa "1" để bộ lọc sẽ hoạt động ...

Khi làm việc với ví dụ sau:

echo "1: " | awk '/1/ -F ":" {print $1}'

Cú pháp lộn xộn và trình thông dịch đã chọn bỏ qua phần F ":" và chuyển sang bộ tách trường mặc định là không gian trống, do đó xuất ra "1:" làm trường thứ nhất và sẽ không có trường thứ hai!

Câu trả lời của JUERGEN chứa cú pháp tốt ...


2

Hoặc bạn có thể sử dụng:

echo "1: " | awk  '/1/{print $1-":"}' 

Đây là phương trình thực sự buồn cười.


1
/1/nghĩa là gì

Tìm một mô hình. Trong trường hợp này "1"
José Dias
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.