Truyền một biến script shell vào lệnh AWK


3

Tôi muốn có thể gọi một kịch bản shell chứa lệnh sau.

awk -F $'\xE7' '{OFS ="¬"} { $3 = sprintf("%010s". $3) ; print $0 }' > outputfile

Nhưng tôi muốn có thể chuyển một biến script shell vào lệnh này sẽ được sử dụng để thay thế $3 trong lệnh AWK.

Làm cách nào để chuyển một biến script shell vào lệnh AWK này?

Câu trả lời:


-1

Báo giá đơn ức chế mở rộng. Chuyển chúng lên.

awk ... '...'"$foo"'...' ...

1
Không! Điều này xử lý giá trị của foo, được bao quanh bởi dấu ngoặc kép, như một đoạn của kịch bản awk. Nếu $foo chứa dấu ngoặc kép hoặc dấu gạch chéo ngược, tất cả địa ngục có thể bị phá vỡ. Xem Câu trả lời của Dennis cho một giải pháp hoạt động.
Gilles

@Gilles: Không có xung quanh bởi dấu ngoặc kép. Shell loại bỏ tất cả các dấu ngoặc kép bên ngoài trước khi chuyển và vì các dấu ngoặc đơn được đóng trước khi dấu ngoặc kép được mở và ngược lại, chúng được coi là dấu ngoặc kép bên ngoài.
Ignacio Vazquez-Abrams

Ồ, đúng rồi, tôi đã viết sai các trích dẫn của bạn và những gì bạn viết là hợp lý - giá trị của foo trở thành một đoạn của kịch bản awk - nhưng sau đó tôi không thấy nó trả lời câu hỏi như thế nào. @ mờ
Gilles

Gilles đúng nếu $foo có thể chứa các giá trị không được xác nhận, nó có thể gây rối nghiêm trọng cho tập lệnh của bạn.
dubiousjim

... Hãy xem xét những gì xảy ra với awk '$1=='"$foo"'{print $3}' khi nào $foo đánh giá z{next} {print "garbage"} 0. Và ngay cả trong trường hợp thông thường $foo chứa một chuỗi thông thường, bạn sẽ phải đảm bảo vị trí tập lệnh của mình " s xung quanh nó. Câu trả lời của Dennis cho thấy cách đúng đắn để làm điều này.
dubiousjim

5

Cách chính xác để làm điều này là sử dụng tính năng chuyển biến của AWK. Ngoài ra, có lẽ bạn chỉ cần thiết lập OFS một lần, vì vậy bạn nên làm điều đó trong BEGIN mệnh đề.

awk -F $'\xE7' -v awkvar="$shellvar" 'BEGIN {OFS ="¬"} { $3 = sprintf("%010s". $3) ; print $0, awkvar }' input file > outputfile

Bạn cũng có thể sử dụng -v để thiết lập OFS:

awk -F $'\xE7' -v awkvar="$shellvar" -v OFS ="¬" '{ $3 = sprintf("%010s". $3) ; print $0, awkvar }' input file > outputfile

Tôi vừa thêm biến vào print tuyên bố vì tôi không biết chính xác làm thế nào bạn muốn sử dụng nó.


@Gilles: Báo giá không cần thiết cho loại bài tập đó.
Dennis Williamson

Huh? Theo như vỏ awkvar="$shellvar" là từ thứ năm trong lệnh đơn giản. Không có dấu ngoặc kép, awkvar=$shellvar sẽ trải qua quá trình phân tách trường và mở rộng tên đường dẫn như bình thường.
Gilles

@Gilles: Bạn nói đúng. Xin lỗi, tôi đã suy nghĩ về các quy tắc chuyển nhượng vỏ bình thường.
Dennis Williamson

2

awk có ENVIRON mảng để truy cập môi trường:

$ FOO=bar awk 'BEGIN{print ENVIRON["FOO"]}'
bar

Điều này cũng hoạt động, nhưng -v kỹ thuật là giải pháp chung ưa thích.
dubiousjim
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.