কোনও ফাইলের মাঝখানে নির্দিষ্ট লাইন প্রদর্শন করতে দ্রুত ইউনিক্স কমান্ড?


206

কোনও সার্ভারের সাথে কোনও সমস্যা এবং আমার একমাত্র লগ ফাইলটি ডিবাগ করার চেষ্টা করা হচ্ছে একটি 20 জিবি লগ ফাইল (কোনও টাইমস্ট্যাম্প এমনকি নেই! লোকেরা System.out.println()লগিং হিসাবে কেন ব্যবহার করবে ? উত্পাদনে ?!)

গ্রেপ ব্যবহার করে, আমি ফাইলটির এমন একটি অঞ্চল খুঁজে পেয়েছি যা আমি 347340107 লাইনটিতে দেখতে চাই।

এর মতো কিছু করা ছাড়াও

head -<$LINENUM + 10> filename | tail -20 

... যা headলগ ফাইলের প্রথম 347 মিলিয়ন লাইনগুলি পড়তে হবে, এমন কোন দ্রুত এবং সহজ কমান্ড রয়েছে যা কনসোলে 347340100 - 347340200 (উদাহরণস্বরূপ) লাইন ডাম্প করবে?

আপডেট আমি সম্পূর্ণরূপে ভুলে গেছি যে গ্রেপ একটি ম্যাচের চারদিকে প্রসঙ্গ মুদ্রণ করতে পারে ... এটি ভালভাবে কাজ করে। ধন্যবাদ!


আমি কল্পনা করব যে গ্রেপকে পুরো ফাইলটি অনুসন্ধান করতে হবে এটি করার জন্য অবশ্যই কোনও সিপিইউ কম নিবিড় উপায় থাকতে হবে।
ওজব্লাস 3

উত্তর:


69

জিএনইউ-গ্রেপ দিয়ে আপনি ঠিক বলতে পারেন

গ্রেপ - কনটেক্সট = 10 ...

7
বা আরও সুনির্দিষ্টভাবে 10 টি রেখা আগে: গ্রেপ-বি 10 ... বা 10 লাইন পরে:
গ্রেপ

17
এই কমান্ডটি কাজ করছে না, নীচে সেড-এন '<স্টার্ট> <end> পি' কাজ করছে
বাসভ

5
এটি আসলে আপনি যা চান তা নয় কারণ ম্যাচ শীর্ষে থাকলেও এটি পুরো ফাইলটি প্রক্রিয়া করবে। এই সময়ে একটি মাথা / লেজ বা লেজ / মাথা কম্বো অনেক বেশি কার্যকর।
Sklivvz

3
এটি জিজ্ঞাসা করা প্রশ্নটি মোটেও সন্তুষ্ট করে না কারণ এটি যেমন একটি নির্দিষ্ট লাইন আউটপুট দেওয়ার কোনও উপায় সরবরাহ করে না , যেমনটি বলা হয়েছিল।
ক্রিস রসিস

1
এটি আসলে যা বলা হয়েছিল তা নয়। @ ম্যাট বি, আপনি কেন এই উত্তরটি স্বীকার করবেন না?
ব্যবহারকারী 1271772

390

আপনি যদি লাইন নম্বরটি জানেন তবে অন্য কিছুই সমাধান করেন নি তবে আমি আরও দুটি সমাধান পেয়েছি (কোনও গ্রেপ সম্ভব নয়):

ধরে নিচ্ছি আপনার 20 থেকে 40 লাইনের দরকার আছে

sed -n '20,40p;41q' file_name

অথবা

awk 'FNR>=20 && FNR<=40' file_name

6
+1: যদিও আপনি মুদ্রণের পরে প্রস্থান করতে চান। ফাইলটি যদি সত্যিই বিশাল হয় তবে কিছু কর্মক্ষমতা বেনিফিট অফার করতে পারে।
জয়পাল সিং

awk 'NR> = 20 && NR <= 40' ফাইলের নাম
সুদীপ্ত বসাক

2
sed -n '20, 40p; 41q 'ফাইল_নামটি তখন ছাড়ার জন্য।
স্নিগ্ধা বাত্রা

1
বিশেষত, সেগুলি শুরু এবং শেষ লাইন সংখ্যাগুলি। আপনি যদি বড় ফাইল হন তবে এটি হবে '12345678,12345699p'
কোড বিলোপকারী

1
যোগ করার সাথে সাথে @ কোডএবমিনেটরের মন্তব্যে লাইন ছেড়ে41q যাওয়ার নির্দেশ দেয় । 41
Brice

116
# print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3,  efficient on large files 

পদ্ধতি 3 বড় ফাইলগুলিতে দক্ষ

নির্দিষ্ট লাইনগুলি প্রদর্শন করার দ্রুততম উপায়


আমি একক লাইনের পরিবর্তে কোনও পরিসরটি ব্যবহার করার পদ্ধতি 3 কীভাবে মানিয়ে নেব তা চেষ্টা করার চেষ্টা করছি, তবে আমি ভয় পাচ্ছি যে আমার সিড-ফু কাজটি শেষ করে না।
জিয়াং চিয়ামিওভ

9
@ জিওনজিচিয়ামিওভ কীভাবে 1-500 মুদ্রণের জন্য '1,500p; 501Q' সেড করবেন?
স্যাম

3
প্রথম দুটি লাইন / পদ্ধতিগুলি কম দক্ষ হওয়ার কারণ, তারা লাইন 52 এর পরে সমস্ত লাইনের সমাপ্তি অব্যাহত রাখে, যেখানে # 3 লাইন 52 মুদ্রণের পরে বন্ধ হয়ে যায়
ফ্লো 2 কে

1
সমস্ত যুক্তি কী করে তা ব্যাখ্যা করে এই উত্তরটি উপকৃত হবে।
ব্রাম ভ্যানরোয়

25

না নেই, ফাইলগুলি লাইন-ঠিকানাযোগ্য নয়।

কোনও পাঠ্য ফাইলে লাইন এনটির সূচনা পাওয়ার জন্য ধ্রুবক-সময় উপায় নেই । আপনাকে অবশ্যই ফাইলটি স্ট্রিম করতে হবে এবং নিউলাইনগুলি গণনা করতে হবে।

আপনার কাজটি করতে হবে সবচেয়ে সহজ / দ্রুততম সরঞ্জামটি ব্যবহার করুন। আমার কাছে ব্যবহার headকরে তোলে অনেক চেয়ে বেশি জ্ঞান grep, যেহেতু আধুনিক পথ আরো জটিল। আমি " grepধীর গতি" বলছি না , এটি সত্যই নয়, তবে headএই ক্ষেত্রেটির চেয়ে এটি দ্রুত হলে আমি অবাক হব । headমূলত এটি একটি বাগ হতে চাই ।


2
বাইটগুলিতে লাইনগুলি প্রস্থ নির্ধারিত না হওয়া পর্যন্ত, আপনি ফাইলের শুরু থেকে নতুন রেখার অক্ষর গণনা না করে কোথায় ফাইল পয়েন্টারটি সরিয়ে ফেলবেন তা আপনি জানেন না।
জোসেফ লাস্ট

এটি প্রশ্নের উত্তর দেয় না। কোনও লেখকের কাছ থেকে সমালোচনা বা স্পষ্টতার জন্য অনুরোধ জানাতে, তাদের পোস্টের নীচে একটি মন্তব্য দিন।
এক্সিউমা

@ ইজহুমা আপনি ঠিক বলেছেন আমি আবার লিখেছি। সাত বছর আগে আমার বিড়বিড় হয়েছে। :)
বিনোদন

20

কি সম্পর্কে:

tail -n +347340107 filename | head -n 100

আমি এটি পরীক্ষা করিনি, তবে আমি মনে করি এটি কার্যকর হবে।


না, সাধারণত লেজটির সীমা 256 শেষ কিলোবাইট বা অনুরূপ, সংস্করণ এবং ওএসের উপর নির্ভর করে।
অ্যান্টি রাইত্সালি

Ess ইয়াসির মিলার
dctremblay

13

আমি কেবল lessand োকা পছন্দ করি

  • টাইপিং 50%এতে যান অর্ধেক ফাইলে,
  • 43210G 43210 লাইনে যেতে
  • :43210 একই কাজ করতে

এবং এধরনের জিনিসপত্র.

আরও উন্নত: vসম্পাদনা শুরু করতে আঘাত করুন (অবশ্যই, ভিএম!), সেই স্থানে। এখন, নোট করুন যে vimএকই কী বাঁধাই আছে!


12

আমি প্রথমে কয়েকটি ছোট ফাইলগুলিতে ফাইলটি বিভক্ত করতাম

$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix

এবং তারপরে ফলাফল প্রাপ্ত ফাইলগুলিতে গ্রেপ করুন।


সম্মত হয়েছেন, সেই লগ আপটি ভাঙ্গুন এবং তা সঠিকভাবে করার জন্য ক্রোন জব তৈরি করুন। লোগ্রোটেট বা অনুরূপ কিছু ব্যবহার করুন যাতে এগুলি এত বিশাল থেকে বাঁচতে পারে।
তানজ

9

আপনি exকমান্ডটি ব্যবহার করতে পারেন , একটি আদর্শ ইউনিক্স সম্পাদক (এখন ভিমের অংশ), যেমন

  • একটি একক লাইন প্রদর্শন করুন (উদাহরণস্বরূপ দ্বিতীয় এক):

    ex +2p -scq file.txt

    সংশ্লিষ্ট সেড সিনট্যাক্স: sed -n '2p' file.txt

  • রেখার পরিসীমা (উদাহরণস্বরূপ 2-5 লাইন):

    ex +2,5p -scq file.txt

    সিড সিনট্যাক্স: sed -n '2,5p' file.txt

  • প্রদত্ত রেখা থেকে শেষ অবধি (উদাহরণস্বরূপ ফাইলের শেষ থেকে পঞ্চম):

    ex +5,p -scq file.txt

    সিড সিনট্যাক্স: sed -n '2,$p' file.txt

  • একাধিক লাইন ব্যাপ্তি (যেমন 2-4 এবং 6-8 লাইন):

    ex +2,4p +6,8p -scq file.txt

    সিড সিনট্যাক্স: sed -n '2,4p;6,8p' file.txt

উপরের কমান্ডগুলি নিম্নলিখিত পরীক্ষার ফাইল দিয়ে পরীক্ষা করা যেতে পারে:

seq 1 20 > file.txt

ব্যাখ্যা:

  • +অথবা -cকমান্ডটি অনুসরণ করে - ফাইলটি পড়ার পরে (vi / vim) কমান্ডটি কার্যকর করুন,
  • -s - নীরব মোড, ডিফল্ট আউটপুট হিসাবে বর্তমান টার্মিনাল ব্যবহার করে,
  • qএর পরে -cসম্পাদক ছাড়ার কমান্ড দেওয়া হয় ( !জোর করে প্রস্থান করার জন্য যুক্ত করুন, যেমন -scq!)।

6

আপনার লাইন নম্বরটি যদি 100 টি পড়তে হয়

head -100 filename | tail -1

6

পাওয়া ack

উবুন্টু / ডেবিয়ান ইনস্টল:

$ sudo apt-get install ack-grep

তারপরে চালান:

$ ack --lines=$START-$END filename

উদাহরণ:

$ ack --lines=10-20 filename

থেকে $ man ack:

--lines=NUM
    Only print line NUM of each file. Multiple lines can be given with multiple --lines options or as a comma separated list (--lines=3,5,7). --lines=4-7 also works. 
    The lines are always output in ascending order, no matter the order given on the command line.

1
এটি, আমার কাছে এখানে সমস্ত উত্তরগুলির মধ্যে সবচেয়ে স্বজ্ঞাত সিন্টেক্স সহ কমান্ডের মতো বলে মনে হচ্ছে।
nzn

10 জানুয়ারী, 2019 তে 2.999_06 সংস্করণ থেকে --linesপ্যারামিটারটি সরানো হয়েছে।
পোড়া

4

সেডগুলি লাইনগুলি গণনা করার জন্য খুব বেশি ডেটা পড়তে হবে। কেবলমাত্র শর্টকাটই সম্ভব হবে যদি ফাইলটিতে কাজ করার জন্য প্রসঙ্গ / আদেশ থাকে। উদাহরণস্বরূপ যদি কোনও নির্দিষ্ট প্রস্থের সময় / তারিখ ইত্যাদির সাথে লগ লাইন থাকে তবে আপনি নির্দিষ্ট তারিখের / বারের জন্য ফাইলগুলির মাধ্যমে বাইনারি অনুসন্ধানের জন্য চেহারা ইউনিক্স ইউটিলিটিটি ব্যবহার করতে পারেন


4

ব্যবহার

x=`cat -n <file> | grep <match> | awk '{print $1}'`

এখানে আপনি লাইন নম্বর পাবেন যেখানে ম্যাচটি ঘটেছে।

100 টি লাইন প্রিন্ট করতে এখন আপনি নীচের কমান্ডটি ব্যবহার করতে পারেন

awk -v var="$x" 'NR>=var && NR<=var+100{print}' <file>

অথবা আপনি "সেড" ব্যবহার করতে পারেন

sed -n "${x},${x+100}p" <file>

আপনার যদি একাধিক ম্যাচ থাকে তবে প্রথম ম্যাচের জন্য "awk 'এনআর == 1 {প্রিন্ট করুন $ 1}" এবং আরও
রমনা রেড্ডি

2

সঙ্গে sed -e '1,N d; M q'আপনি লাইন প্রিন্ট করব n + 1 এম এটি এখন করা সম্ভবত একটু ভাল তারপর grep -Cযেমন একটি প্যাটার্ন লাইনের মেলানোর চেষ্টা করে না।


-eএখানে isচ্ছিক।
ফ্লো 2 কে

2

Sklivvz এর উত্তরে বিল্ডিং, এখানে একটি দুর্দান্ত ফাংশন যা কোনও একটি .bash_aliasesফাইল রাখতে পারে। ফাইলটির সামনে থেকে জিনিসগুলি মুদ্রণের সময় এটি বিশাল ফাইলগুলিতে দক্ষ।

function middle()
{
    startidx=$1
    len=$2
    endidx=$(($startidx+$len))
    filename=$3

    awk "FNR>=${startidx} && FNR<=${endidx} { print NR\" \"\$0 }; FNR>${endidx} { print \"END HERE\"; exit }" $filename
}

1

A থেকে একটি লাইন প্রদর্শন করতে <textfile>তার দ্বারা <line#>, শুধু এই একটি করুন:

perl -wne 'print if $. == <line#>' <textfile>

আপনি যদি নিয়মিত অভিব্যক্তি সহ বিভিন্ন রেখার রেখা প্রদর্শন করার জন্য আরও শক্তিশালী উপায় চান - গ্রাপ কেন এটি করার জন্য একটি খারাপ ধারণা তা আমি বলব না, এটি মোটামুটি সুস্পষ্ট হওয়া উচিত - এই সাধারণ অভিব্যক্তিটি আপনাকে আপনার রেঞ্জটি একটিতে দেখিয়ে দেবে single 20 গিগাবাইট টেক্সট ফাইলগুলির সাথে ডিল করার সময় আপনি যা চান সেটি একক পাস:

perl -wne 'print if m/<regex1>/ .. m/<regex2>/' <filename>

(টিপ: যদি আপনার রেজেক্স এতে /থাকে তবে m!<regex>!পরিবর্তে এর মতো কিছু ব্যবহার করুন)

এই প্রিন্ট আউট হবে <filename>লাইন মিল দিয়ে শুরু <regex1>পর্যন্ত (এবং সহ) লাইন মিলগুলি <regex2>

কয়েকটা টুইট কীভাবে এটিকে আরও শক্তিশালী করে তুলতে পারে তা দেখতে কোনও উইজার্ড লাগে না।

শেষ কথা: পার্ল, যেহেতু এটি একটি পরিণত ভাষা, গতি এবং পারফরম্যান্সের পক্ষে অনেকগুলি লুকানো বর্ধন রয়েছে। এটিকে মনে রেখে, এটি এ জাতীয় ক্রিয়াকলাপের স্পষ্ট পছন্দ হিসাবে এটি মূলত বড় লগ ফাইল, পাঠ্য, ডাটাবেস, ইত্যাদি পরিচালনা করার জন্য তৈরি হয়েছিল makes


সত্যিই, আমার কাছে এটি মনে হয় না, যেহেতু যখন একটি পার্ল কমান্ড বলার চেয়ে জটিল হয় তখন 2+ প্রোগ্রাম একসাথে চালিত হয় (আরও পৃষ্ঠায় নীচে), এবং আমার মনে হয় আপনি আসলেই বলছেন কারণ আমি আরও টাইপ করেছি এমন একটি ব্যাখ্যা যা আপনাকে পড়তে হবে, যেহেতু
পৃষ্ঠের

নোট করুন যে ব্যবহারকারী বিভিন্ন রেখার জন্য চেয়েছিল - আপনার উদাহরণটি যদিও তুচ্ছভাবে অভিযোজিত হতে পারে।
Sklivvz


0

পার্ল দিয়ে সহজ! আপনি যদি কোনও ফাইল থেকে 1, 3 এবং 5 লাইন পেতে চান তবে / etc / passwd বলুন:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd

1
আপনি বলছেন এটি কুয়াশা দিয়ে খুব সহজ, তবে আপনি কি এর পরিবর্তে পার্লে এটি করেছিলেন?
বন্দী 13

0

আমি আশ্চর্য হয়েছি মাত্র অন্য একটি উত্তর (রমন রেড্ডির দ্বারা) আউটপুটটিতে লাইন নম্বর যুক্ত করার পরামর্শ দিয়েছে। নিম্নলিখিত লাইন নম্বরটির জন্য অনুসন্ধান করে এবং আউটপুটটিকে রঙ দেয়।

file=FILE
lineno=LINENO
wb="107"; bf="30;1"; rb="101"; yb="103"
cat -n ${file} | { GREP_COLORS="se=${wb};${bf}:cx=${wb};${bf}:ms=${rb};${bf}:sl=${yb};${bf}" grep --color -C 10 "^[[:space:]]\\+${lineno}[[:space:]]"; }

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