আমি কীভাবে কোনও awk স্ক্রিপ্টে শেল ভেরিয়েবল ব্যবহার করব?


290

আমি কোনও awkস্ক্রিপ্টে বাহ্যিক শেল ভেরিয়েবলগুলি পাস করার কিছু উপায় খুঁজে পেয়েছি তবে আমি 'এবং সম্পর্কে বিভ্রান্ত "

প্রথমত, আমি একটি শেল স্ক্রিপ্ট দিয়ে চেষ্টা করেছি:

$ v=123test
$ echo $v
123test
$ echo "$v"
123test

তারপরে অদ্ভুত চেষ্টা করলেন:

$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123

পার্থক্য কেন?

শেষ পর্যন্ত আমি এটি চেষ্টা করেছিলাম:

$ awk 'BEGIN{print " '$v' "}'
$  123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1:             ^ unexpected newline or end of string 

আমি এই সম্পর্কে বিভ্রান্ত।


2
আমি নীচে দেখানো মত -v পছন্দ করি, তবে কীভাবে শাঁস থেকে জিনিসগুলি রক্ষা করা যায় সে সম্পর্কে চিন্তাভাবনা করা এটি সত্যই দুর্দান্ত ব্যায়াম। এটির মাধ্যমে কাজ করে, আমার প্রথম কাটাটি স্পেস এবং ডলারের লক্ষণগুলিতে ব্যাকস্ল্যাশ ব্যবহার করে। এখানে উদাহরণগুলি আমার সময়ের পক্ষে ভাল ছিল তা বলা বাহুল্য well
ক্রিস


যদি আপনার খালি অনুসন্ধানে নিয়মিত প্রকাশের প্রয়োজন হয় তবে আপনি রাখতে পারবেন না /var/। পরিবর্তে, টিল্ড ব্যবহার করুন:awk -v var="$var" '$0 ~ var'
নোয়াম মানস

উত্তর:


496

এর মধ্যে শেল ভেরিয়েবলগুলি পাওয়া awk

বিভিন্ন উপায়ে করা হতে পারে। কিছু অন্যদের চেয়ে ভাল। এটি তাদের বেশিরভাগটি আবরণ করা উচিত। আপনার মতামত থাকলে নীচে ছেড়ে দিন। v1.5


ব্যবহার -v (সর্বোত্তম উপায়, সর্বাধিক বহনযোগ্য)

-vবিকল্পটি ব্যবহার করুন : (পিএস পরে কোনও স্থান ব্যবহার করুন -vবা এটি কম পোর্টেবল হবে Eg যেমন, awk -v var=না awk -vvar=)

variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two

এটি বেশিরভাগের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত awkএবং ভেরিয়েবলটি পাওয়া যায়BEGIN ব্লকটিতেও :

আপনার যদি একাধিক ভেরিয়েবল থাকে:

awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'

সতর্কতা । এড মর্টন যেমন লিখেছেন, এস্কেপ সিকোয়েন্সগুলি ব্যাখ্যা করা হবে তাই \tআসল হয়ে ওঠে tabএবং \tযদি এটি আপনি অনুসন্ধান করেন তবে তা নয় । ENVIRON[]এটি ব্যবহার করে বা এর মাধ্যমে অ্যাক্সেসের মাধ্যমে সমাধান করা যেতে পারেARGV[]

পিএস যদি আপনি পৃথক হিসাবে তিনটি উল্লম্ব বার পছন্দ করেন তবে |||এটি এড়ানো যায় না, তাই ব্যবহার করুন-F"[|][|][|]"

প্রোগ্রাম / ফাংশন सराণ থেকে ডেটা পাওয়ার উদাহরণ উদাহরণ awk(এখানে তারিখটি ব্যবহৃত হয়)

awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'

কোড ব্লকের পরে পরিবর্তনশীল

এখানে আমরা awkকোডের পরে ভেরিয়েবল পাই । BEGINব্লকটিতে আপনার চলকের প্রয়োজন না থাকলে এটি কাজ করবে :

variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
  • একাধিক ভেরিয়েবল যুক্ত করা হচ্ছে:

awk '{print a,b,$0}' a="$var1" b="$var2" file

  • এই পদ্ধতিতে আমরা FSপ্রতিটি ফাইলের জন্য পৃথক ফিল্ড পৃথককারীও সেট করতে পারি ।

awk 'some code' FS=',' file1.txt FS=';' file2.ext

  • কোড ব্লকের পরে পরিবর্তনশীল ব্লকের জন্য কাজ করবে না BEGIN:

echo "input data" | awk 'BEGIN {print var}' var="${variable}"


এখানে স্ট্রিং

চলকগুলি এখানে সমর্থন করে এমন শেলগুলি (বাশ সহ) থেকে awkএকটি স্ট্রিং ব্যবহার করে যুক্ত করা যেতে পারে :

awk '{print $0}' <<< "$variable"
test

এটি যেমন:

printf '%s' "$variable" | awk '{print $0}'

PS এই পরিবর্তনশীলটিকে একটি ফাইল ইনপুট হিসাবে বিবেচনা করে।


ENVIRON ইনপুট

ট্রুওয়াই যেমন লিখেছেন, আপনি পরিবেশ পরিবর্তনশীলগুলিENVIRON মুদ্রণের জন্য এটি ব্যবহার করতে পারেন । এডাব্লুকে চালানোর আগে একটি ভেরিয়েবল সেট করা, আপনি এটি এর মতো মুদ্রণ করতে পারেন:

X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash

ARGV ইনপুট

স্টিভেন পেনি যেমন লেখেন, ARGVততক্ষণে আপনি তথ্যটি বিশৃঙ্খলাতে আনতে ব্যবহার করতে পারেন :

v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data

কোডটি নিজেই ডেটা পেতে কেবল শুরুই নয়:

v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test

কোডের মধ্যে পরিবর্তনশীল: সতর্কতার সাথে ব্যবহার করুন

আপনি awkকোডের মধ্যে একটি ভেরিয়েবল ব্যবহার করতে পারেন তবে এটি অগোছালো এবং পড়া শক্ত এবং আপনার Charles Duffyপয়েন্ট হিসাবে এই সংস্করণটি কোড ইঞ্জেকশনেরও শিকার হতে পারে। কেউ যদি ভেরিয়েবলে খারাপ জিনিস যুক্ত করে, awkকোডের অংশ হিসাবে এটি কার্যকর করা হবে ।

কোডের মধ্যে ভেরিয়েবলটি বের করে এটি কাজ করে, তাই এটি এর একটি অংশে পরিণত হয়।

আপনি যদি awkভেরিয়েবলের ব্যবহারের সাথে পরিবর্তনশীল পরিবর্তন করতে চান তবে আপনি এটি এভাবে করতে পারেন তবে সাধারণ ভেরিয়েবলের জন্য এটি ব্যবহার করবেন না।

variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two

কোড ইঞ্জেকশনের উদাহরণ এখানে:

variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000

আপনি awkএইভাবে প্রচুর কমান্ড যুক্ত করতে পারেন । এমনকি এটি বৈধ কমান্ডের সাহায্যে ক্রাশ করুন।


অতিরিক্ত তথ্য:

ডাবল উদ্ধৃতি ব্যবহার

কোট ভেরিয়েবলের দ্বিগুণ করা সর্বদা ভাল "$variable"
যদি না তবে একক লাইন একটি দীর্ঘ একক লাইন হিসাবে যুক্ত করা হবে।

উদাহরণ:

var="Line one
This is line two"

echo $var
Line one This is line two

echo "$var"
Line one
This is line two

অন্যান্য ত্রুটিগুলি আপনি ডাবল উদ্ধৃতি ছাড়াই পেতে পারেন:

variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1:    ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1:    ^ syntax error

এবং একক উদ্ধৃতি সহ, এটি ভেরিয়েবলের মান প্রসারিত করে না:

awk -v var='$variable' 'BEGIN {print var}'
$variable

AWK এবং ভেরিয়েবল সম্পর্কে আরও তথ্য

এই প্রশ্ন জিজ্ঞাসা করুন


2
"অগোছালো এবং পড়ার পক্ষে কঠিন" কোডটি যখন সরাসরি স্ট্রিংকে অ্যাজকেডে প্রতিস্থাপন করে তখন কোড ইনজেকশনের আরও গুরুত্বপূর্ণ সুরক্ষার উদ্বেগকে উপেক্ষা করে।
চার্লস ডাফি

উপরের উত্তরটি পড়া আমি ত্রুটি ছাড়াই আমার স্ক্রিপ্টটি চালাতে পারি তবে এটি কাজ করে না: awk -v repo = "$ 1" -v ট্যাগ = "$ 2" '{সাব (/ চিত্র: registryabx.azurecr.io \ / { মুদ্রণ রেপো}: ([a-z0-9] +) $ /, "চিত্র: registryabc.azurecr। io / {প্রিন্ট রেপো}: {মুদ্রণ ট্যাগ}");} 1 './services/appscompose.yaml >> newcompose.yaml। নেস্টেড প্রথম বন্ধনী কারণ Is?
ডারিয়ন ব্যাডলিডন

@DarionBadlydone এই চেষ্টা awk -v repo="$1" -v tag="$2" 'BEGIN {print "repo="repo,"tag="tag}'। এটি ভেরিয়েবল প্রিন্ট করে কিনা তা দেখতে পাবে। আপনি যদি তা বের করতে না পারেন তবে একটি নিজস্ব প্রশ্ন পোস্ট করুন।
জোটনে

@ জোত্ন হ্যাঁ এটি মানগুলি মুদ্রণ করে তাই আমি এইভাবে চেষ্টা করেছি: awk -v রেপো = "$ 1" -ভি ট্যাগ = "$ 2" '{মুদ্রণ "{উপ (/ চিত্র: registryabc.azurecr.io/"repo" :( [a-z0-9] +) $ /, image "চিত্র: registryabc.azurecr.io/"repo":"tag"\") ;}1"} './services/appscompose.yaml >> newcompose.yaml তবে আশানুরূপে কাজ করছে না। এটি উত্স ফাইলের প্রতিটি লাইন মুদ্রিত কমান্ড দিয়ে প্রতিস্থাপন করে
ডারিয়ন ব্যাডলিডোন

@ জোটনে আমি সেড দিয়ে এটি করেছি, যাইহোক আপনাকে ধন্যবাদ
ড্যারিয়ন ব্যাডলিডোন

28

মনে হয় ভাল-বৃদ্ধ ENVIRON অন্তর্নির্মিত হ্যাশটি মোটেই উল্লেখ করা হয়নি। এর ব্যবহারের একটি উদাহরণ:

$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt

4
এটি একটি ভাল পরামর্শ কারণ এটি ডেটা ভারব্যাটিম পাস করে। -vযখন মানটিতে ব্যাকস্ল্যাশ থাকে তখন কাজ করে না।
সে অন্য লোক

2
এই টুইটটি আমার পছন্দ নয় আমি ভেবেছিলাম আমি যদি awk -v x='\c\d' ...এটি ব্যবহার করি তবে এটি সঠিকভাবে ব্যবহৃত হবে। তবে কখন ছদ্মবেশটিx মুদ্রিত হয় বিখ্যাত: ত্রুটির বার্তা ... ধন্যবাদ! awk: warning: escape sequence '\c' treated as plain 'c'
সত্য

এটি সঠিকভাবে কাজ করে - সঠিকভাবে এই প্রসঙ্গে পালাবারের ক্রমগুলি প্রসারিত করার অর্থ এটি কীভাবে -vকাজ করার জন্য তৈরি করা হয়েছিল যাতে আপনি \tভেরিয়েবলটি ব্যবহার করতে পারেন এবং উদাহরণস্বরূপ এটি ডেটাতে একটি আক্ষরিক ট্যাবের সাথে মেলে। যদি এটি আপনি চান এমন আচরণ না হয় তবে -vআপনি ব্যবহার করেন না ARGV[]বা ব্যবহার করেন না ENVIRON[]
এড মর্টন

9

হ্যান্ডেল করা শেল ভেরিয়েবলগুলিতে আপনি কীভাবে ব্যাকস্ল্যাশগুলি চান তা নির্ভর করে এর মধ্যে যে avarকোনওটি ব্যবহার করুন ( svarএটি একটি শূন্য ভেরিয়েবল , শেল ভেরিয়েবল):

awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file

বিশদ এবং অন্যান্য বিকল্পগুলির জন্য http://cfajohnson.com/shell/cus-faq-2.html#Q24 দেখুন । উপরের প্রথম পদ্ধতিটি প্রায় সর্বদা আপনার সেরা বিকল্প এবং সবচেয়ে সুস্পষ্ট শব্দার্থক শব্দ রয়েছে।


6

আপনি পরিবেশের পরিবর্তনশীল ( ) এর একটি ভেরিয়েবল নাম ( ) এবং একটি মান ( ) সহ কমান্ড-লাইন বিকল্পে পাস করতে পারেন :-vv="${v}"

% awk -vv="${v}" 'BEGIN { print v }'
123test

বা এটিকে আরও স্পষ্ট করার জন্য (আরও কম সংখ্যক v)

% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test

3

আপনি এআরজিভি ব্যবহার করতে পারেন:

v=123test
awk 'BEGIN {print ARGV[1]}' "$v"

মনে রাখবেন আপনি যদি শরীরে চালিয়ে যেতে চলেছেন তবে আপনাকে এআরজিসি সামঞ্জস্য করতে হবে:

awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"

1

আমি মাত্র "লুপের জন্য" জোটের উত্তর পরিবর্তন করেছি।

for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done

1
এটি কেবল আউকের -vবিকল্পটি কীভাবে ব্যবহার করতে হবে তার আরও একটি উদাহরণ বলে মনে হচ্ছে যা বিদ্যমান উত্তরগুলির মধ্যে ইতিমধ্যে উল্লিখিত ছিল। আপনি যদি লুপে আওক চালাবেন তা দেখাতে চান, এটি সত্যিই আলাদা প্রশ্ন।
ট্রিপলি

0

লগ ফাইলের লাইনের শুরুতে আমাকে তারিখটি প্রবেশ করতে হয়েছিল এবং এটি নীচের মত সম্পন্ন হয়েছে:

DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log

এটি সংরক্ষণ করতে অন্য ফাইলে পুনর্নির্দেশ করা যেতে পারে


ডাবল উক্তি - একক উক্তি - ডাবল উদ্ধৃতিটি আমার কাজটি করার জন্য ঠিক আমার প্রয়োজন ছিল।
ব্যবহারকারী53029

2
কোড ইনজেকশন দুর্বলতার কারণে আপনার ব্যবহার করা উচিত নয় এমন একটি পদ্ধতি হিসাবে এটি ইতিমধ্যে গৃহীত উত্তরে উল্লেখ করা হয়েছিল। সুতরাং এখানে তথ্য অপ্রয়োজনীয় (ইতিমধ্যে স্বীকৃত উত্তরে বর্ণিত), এবং অসম্পূর্ণ (এই পদ্ধতিতে সমস্যাগুলি উল্লেখ করে না)।
জেসন এস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.