2013-04-16 30 views
22

Đặt tên máy chủ theo định dạng aaa0.bbb.ccc, tôi muốn trích chuỗi con đầu tiên trước ., nghĩa là, aaa0 trong trường hợp này. Tôi sử dụng script awk sau đây để làm như vậy,Sử dụng Awk để trích xuất chuỗi con

echo aaa0.bbb.ccc | awk '{if (match($0, /\./)) {print substr($0, 0, RSTART - 1)}}' 

Trong khi kịch bản chạy trên một máy A sản xuất aaa0, chạy trên máy B chỉ sản xuất aaa, mà không 0 cuối cùng. Cả hai máy chạy Ubuntu/Linaro, nhưng A chạy phiên bản mới hơn của awk (trố mắt với phiên bản 3.1.8 trong khi B với awk cũ (mawk với phiên bản 1.2)

Tôi yêu cầu nói chung, làm thế nào để viết một kịch bản awk tương thích rằng thực hiện cùng các chức năng ...

Trả lời

47

Bạn chỉ muốn thiết lập tách lĩnh vực như . sử dụng tùy chọn -F và in các trường đầu tiên:

$ echo aaa0.bbb.ccc | awk -F'.' '{print $1}' 
aaa0 

cùng một điều nhưng sử dụng cắt:

0.123.
$ echo aaa0.bbb.ccc | cut -d'.' -f1 
aaa0 

Hoặc với sed:

$ echo aaa0.bbb.ccc | sed 's/[.].*//' 
aaa0 

Thậm chí grep:

$ echo aaa0.bbb.ccc | grep -o '^[^.]*' 
aaa0 
4

Hoặc chỉ cần sử dụng cắt:

echo aaa0.bbb.ccc | cut -d'.' -f1 
0

Bạn không cần awk cho điều này ...

echo aaa0.bbb.ccc | cut -d. -f1 
cut -d. -f1 <<< aaa0.bbb.ccc 

echo aaa0.bbb.ccc | { IFS=. read a _ ; echo $a ; } 
{ IFS=. read a _ ; echo $a ; } <<< aaa0.bbb.ccc 

x=aaa0.bbb.ccc; echo ${x/.*/} 

tùy chọn Nặng:

sed: 
echo aaa0.bbb.ccc | sed 's/\..*//' 
sed 's/\..*//' <<< aaa0.bbb.ccc 
awk: 
echo aaa0.bbb.ccc | awk -F. '{print $1}' 
awk -F. '{print $1}' <<< aaa0.bbb.ccc 
+0

Ghi đè, vui lòng cho tôi biết lỗi. Cảm ơn :) – anishsane

1

Bạn không cần bất kỳ lệnh bên ngoài ở tất cả, chỉ cần sử dụng Parameter Expansion trong bash:

hostname=aaa0.bbb.ccc 
echo ${hostname%%.*} 
4

Tôi yêu cầu nói chung, làm thế nào để viết một tập lệnh awk tương thích mà thực hiện cùng chức năng ...

To giải quyết vấn đề trong quesiton của bạn thật dễ dàng. (kiểm tra câu trả lời của người khác).

Nếu bạn muốn viết một kịch bản awk, có thể di chuyển đến bất kỳ triển khai và phiên bản awk nào (gawk/nawk/mawk ...) Nó thực sự là khó, thậm chí nếu có --posix (gawk)

ví dụ:

  • một số awk hoạt động trên chuỗi về nhân vật, một số byte
  • một số hỗ trợ \x thoát, một số không
  • FS thông dịch viên làm việc khác nhau
  • từ khóa/từ dành riêng viết tắt hạn chế
  • một số nhà khai thác hạn chế ví dụ **
  • thậm chí là cùng một máy ảo. (ví dụ như gawk), phiên bản 4.0 và 3.x cũng có sự khác biệt.
  • việc triển khai các chức năng nhất định cũng khác nhau. (vấn đề của bạn là một ví dụ, xem bên dưới)

tất cả các điểm trên đều chỉ nói chung. Quay lại vấn đề của bạn, vấn đề của bạn chỉ liên quan đến tính năng cơ bản của awk. awk '{print $x}' dòng giống như vậy sẽ làm việc tất cả các awks.

Có hai lý do tại sao dòng awk của bạn cư xử khác nhau trên gawk và mawk:

  • bạn sử dụng chức năng substr() sai. đây là nguyên nhân chính. bạn có substr($0, 0, RSTART - 1) số 0 phải là 1, bất kể bạn đang sử dụng dịch vụ nào. mảng awk, chuỗi idx vv là 1-based.

  • gawk và mawk được triển khai substr() khác nhau.

Các vấn đề liên quan