ব্যাশ স্ক্রিপ্টে কোনও ফাইলের প্রথম লাইনটি কীভাবে পাবেন?


249

আমাকে একটি ফাইলের প্রথম লাইনে ব্যাশ ভেরিয়েবল রাখতে হবে। আমার ধারণা এটি গ্রেপ কমান্ডের সাথে রয়েছে তবে লাইন সংখ্যা সীমাবদ্ধ করার কোনও উপায় কি?

উত্তর:


396

headএকটি ফাইল থেকে প্রথম লাইন নেয়, এবং -nপ্যারামিটারটি কতগুলি লাইন বের করা উচিত তা নির্দিষ্ট করতে ব্যবহৃত হতে পারে:

line=$(head -n 1 filename)

3
উল্লেখযোগ্যভাবে readপদ্ধতির চেয়ে বেশি ওভারহেড । $()একটি সাবশেল কাঁটাচামচ করা, এবং একটি বাহ্যিক কমান্ড (যে কোনও বাহ্যিক কমান্ড) ব্যবহার করার অর্থ আপনি execve()লিঙ্কার এবং লোডারকে আহ্বান করছেন (যদি এটি ভাগ করে নেওয়া লাইব্রেরিগুলি ব্যবহার করা হয়, যা সাধারণত ক্ষেত্রে হয়) ইত্যাদি।
চার্লস ডাফি

2
এটি আরও ছোট হতে পারে:line="$(head -1 FILENAME)"
নিকোলে

3
এবং এছাড়াও:line=`head -1 FILENAME`
শাই অ্যালন

চারপাশের ব্যাকটিকগুলি কি সাবস্কেলটি head...খোলা $()আছে?
যায়েম হাবলুটজেল

@ জাইমহাবলুটজেল হ্যাঁ, তারা একই জিনিস, যদিও আমি ব্যক্তিগতভাবে $()দেখতে পাই যে বাক্য গঠনটি দেখতে সহজ, এবং নিখুঁত স্বচ্ছতার উপর মূল্য স্পষ্টতা। gnu.org/software/bash/manual/html_node/…
জোসেফ সিকোরস্কি

61

ব্যাশ ব্যবহার করে প্রথম লাইন পড়তে, readস্টেটমেন্ট ব্যবহার করুন । যেমন

read -r firstline<file

firstline আপনার পরিবর্তনশীল হবে (অন্যকে বরাদ্দ দেওয়ার দরকার নেই)


1
@ সোরিন, cat ... | read VARবেশিরভাগ শেলগুলিতে ব্যর্থ হবে ( zshযতটুকু আমি জানি আমি ব্যতীত ) কারণ পাইপের প্রতিটি উপাদান আলাদা আলাদা সাবশেলে চালিত হবে। অর্থ যে $VARআহরণ শেলের পরিবর্তে সাবশেলে সেট করা হবে (পাইপলাইনটি শেষ হয়ে যাওয়ার সাথে সাথেই এর উপস্থিতি থামবে)। আপনি read VAR <<EOF\n$(cat ...)\nEOF(যেখানে প্রতিটি \nএকটি নতুন লাইন) এর সাথে এটি পেতে পারেন ।
zrajm

@ সোরিন, catখাঁটি ওভারহেড; আরো অনেক কিছু দক্ষ read -r var <fileচেয়ে cat file | readকোন উপায়ে, এমনকি যদি আধুনিক বর্ণিত কারণে ব্যর্থ হয়নি BashFAQ # 24
চার্লস ডাফি 16

... আপনি যদি এর চেয়ে আরও বেশি কিছু জড়িত থাকেন catতবেread -r var < <(otherprog ...)
চার্লস ডাফি

14

এটি filenameভেরিয়েবলের প্রথম লাইনে যথেষ্ট এবং সংরক্ষণ করে $line:

read -r line < filename

আমি এটির জন্যও পছন্দ করি awk:

awk 'NR==1 {print; exit}' file

লাইনটি নিজেই সঞ্চয় করতে var=$(command)সিনট্যাক্সটি ব্যবহার করুন । এই ক্ষেত্রে line=$(awk 'NR==1 {print; exit}' file),।

বা এমনকি sed:

sed -n '1p' file

সমতুল্য সঙ্গে line=$(sed -n '1p' file)


যখন আমরা ভোজন একটি নমুনা দেখতে readসঙ্গে seq 10, যে, 1 থেকে 10 থেকে সংখ্যার একটি ক্রম:

$ read -r line < <(seq 10) 
$ echo "$line"
1

$ line=$(awk 'NR==1 {print; exit}' <(seq 10))
$ echo "$line"
1

1
sed '1!d;q'(বা sed -n '1p;q') আপনার awkযুক্তি নকল করবে এবং ফাইলে আরও পড়া আটকাবে। যেহেতু আমরা শুধুমাত্র প্রথম লাইন চাই, আমরা অন্যথায় সঙ্গে প্রতারণা করতে পারেন sed qবা awk '1;{exit}'বা এমনকি grep -m1 ^(কম কোড, একই অপরিহার্য যুক্তিবিজ্ঞান)। (এটি ডাউনভোট তদন্তের জবাব নয়))
অ্যাডাম কাটজ

@ অ্যাডামক্যাটজ এটি একটি খুব সুন্দর উপায়, ধন্যবাদ! আমি grepখুব স্মার্ট সঙ্গে একটি খুঁজে । আমরা অবশ্যই বলতে পারি head -n 1 file
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

হ্যাঁ, head -n1দ্রুত হবে (লোড করার জন্য ছোট বাইনারি) এবং readদ্রুত হবে (লোড করার কোনও বাইনারি নয়, এটি একটি বিল্টিন)। আমি বিশেষত পছন্দ করি grep -m1 --color .যখন আমি কেবল প্রথম লাইনটি প্রিন্ট করি কারণ এটি লাইনটি খুব রঙ করবে, এটি টেবিল শিরোনামগুলির জন্য দুর্দান্ত করে তুলেছে।
অ্যাডাম কাটজ

12
line=$(head -1 file)

ভাল কাজ করবে। (পূর্ববর্তী উত্তর হিসাবে)। কিন্তু

line=$(read -r FIRSTLINE < filename)

readবিল্ট-ইন বাশ কমান্ডের মতোই গতিতে দ্রুত হবে ।


21
দ্বিতীয় পদ্ধতি লিখিত হিসাবে কাজ করে না, কারণ readকোনও কিছুই মুদ্রণ করে না (তাই lineফাঁকা বাতাস প্রবাহিত হয়), এবং একটি সাবশেলে চালিত করে (সুতরাং FIRSTLINEপ্রথম লাইনে সেট হয়ে যায় তবে কেবল সাবশেলে, সুতরাং এটি পরে পাওয়া যায় না)। সমাধান: স্রেফ ব্যবহার করুনread -r line <filename
গর্ডন ডেভিসন

5

শুধু echoআপনার টার্গেট ফাইলে আপনার সোর্স ফাইলের প্রথম তালিকা।

echo $(head -n 1 source.txt) > target.txt

3
যার head -n 1 source.txt > target.txtজন্য ঠিক একই অর্জন করা হবে।
YoYo

4

প্রশ্নটি কোনটি দ্রুত, এটি জিজ্ঞাসা করা হয়নি, তবে সিডের উত্তর যুক্ত করতে, -n '1p' খারাপ প্লেয়ার করছে কারণ প্যাটার্ন স্পেসটি এখনও বড় ফাইলগুলিতে স্ক্যান করা আছে। কৌতূহলের বাইরে আমি দেখতে পেলাম যে 'মাথা' সরুভাবে জেগে উঠেছে:

# best:
head -n1 $bigfile >/dev/null

# a bit slower than head (I saw about 10% difference):
sed '1q' $bigfile >/dev/null

# VERY slow:
sed -n '1p' $bigfile >/dev/null
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.