ইউনিক্স - মাথা এবং ফাইলের লেজ


131

বলুন আপনার কাছে টেক্সট ফাইল আছে, শীর্ষ 10 টি লাইন এবং নীচের 10 টি ফাইলের এক সাথে দেখতে দেখার কমান্ডটি কী?

উদাহরণস্বরূপ, ফাইলটি যদি 200 লাইন দীর্ঘ হয়, তবে একবারে 1-10 এবং 190-200 টি লাইন দেখুন।


"এক বার যেতে" বলতে কী বোঝ?
cnicutar

টুইটার -10 ফাইলটি ডেটার দিকে তাকাতে হবে না এবং তারপরে আলাদাভাবে লেজ -10 ফাইলে
যাবেন

@toop আপনি একটি বাস্তব কাজ উদাহরণস্বরূপ চান, দেখতে stackoverflow.com/a/44849814/99834
sorin

উত্তর:


208

আপনি কেবল:

(head; tail) < file.txt

এবং যদি আপনার কোনও কারণে পাইপ ব্যবহার করার প্রয়োজন হয় তবে এটি পছন্দ করুন:

cat file.txt | (head; tail)

দ্রষ্টব্য: যদি file.txt এ রেখার সংখ্যা মাথা + ডিফল্ট লেজের পুস্তকের চেয়ে কম হয় তবে নকল লাইনগুলি মুদ্রণ করবে।


54
কড়া কথায় বলতে গেলে এটি আপনাকে মূল ফাইলের লেজ দেয় না, তবে স্ট্রিমের লেজটি ফাইলের headপ্রথম 10 লাইন গ্রাস করেছে। ( head < file.txt; tail < file.txt20 টিরও কম লাইনের সাথে কোনও ফাইলে এটির তুলনা করুন )। মনে রাখা খুব সামান্য একটি বিষয়। (তবে এখনও +1।)
চিপনার

15
খুশী হলাম। আপনি যদি মাথা এবং লেজের অংশগুলির মধ্যে একটি ফাঁক চান: (মাথা; প্রতিধ্বনি; লেজ) <file.txt
সাইমন হিবিস

3
কেন / কীভাবে এটি কাজ করে তা সম্পর্কে কৌতূহল। : একটি নতুন প্রশ্ন যেমন জিজ্ঞাসিত stackoverflow.com/questions/13718242
zellyn

9
@ নামটাল আসলে, আপনি এমনকি এত কিছু নাও পেতে পারেন। যদিও headশুধুমাত্র প্রদর্শন তার ইনপুটের প্রথম 10 লাইন, কোন নিশ্চিত করা হয় যে এটা করা হয়নি গ্রাস অর্ডার 10th লাইন বিভক্তি এটি এটা আরো, জন্য ইনপুট কম যাব lessপ্রদর্শন।
চিপনার

20
দুঃখিত, তবে উত্তরটি কেবলমাত্র কিছু ক্ষেত্রে কার্যকর হয় in seq 100 | (head; tail)আমাকে কেবল প্রথম 10 নম্বর দেয়। কেবলমাত্র বৃহত্তর ইনপুট আকারে (যেমন seq 2000) লেজটি কিছু ইনপুট দেয়।
মডিউলার

18

ed হয় standard text editor

$ echo -e '1+10,$-10d\n%p' | ed -s file.txt

2
যদি ফাইলটিতে 200 টিরও কম লাইন থাকে? এবং আপনি কি জানেন না লাইনের সংখ্যা অব দিদিও?
পল

আমি পরিবর্তন করেছি @Paul sedকরতেed
keV

14

খাঁটি স্রোতের জন্য (যেমন কমান্ড থেকে আউটপুট), আপনি স্ট্রিম কাঁটাচামচ করতে 'টি' ব্যবহার করতে পারেন এবং একটি স্ট্রিম মাথায় এবং একটিতে লেজ প্রেরণ করতে পারেন। এর জন্য বাশ (+ / dev / fd / N) এর '> (তালিকা)' বৈশিষ্ট্যটি ব্যবহার করা দরকার:

( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )

অথবা / dev / fd / N (বা / dev / stderr) ব্যবহার করে জটিল পুনঃনির্দেশ সহ আরও সাবসেল:

( ( seq 1 100 | tee /dev/fd/2 | head 1>&3 ) 2>&1 | tail ) 3>&1
( ( seq 1 100 | tee /dev/stderr | head 1>&3 ) 2>&1 | tail ) 3>&1

(এগুলির কোনওটিই সিএসএস বা টিসিএস-তে কাজ করবে না))

কিছুটা আরও ভাল নিয়ন্ত্রণের জন্য আপনি এই পার্ল কমান্ডটি ব্যবহার করতে পারেন:

COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'

1
স্ট্রিম সমর্থনের জন্য +1। আপনি COMMAND | { tee >(head >&2) | tail; } |& other_commands
স্ট্যাডার

2
বিটিডব্লিউ, এটি বাফার আকারের চেয়ে বড় ফাইলগুলির জন্য বিরতি দেয় (আমার সিস্টেমে 8 কে)। cat >/dev/nullএটি ঠিক করে:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
jfs

আমি সমাধান ভালোবেসেছি, কিন্তু এএ জন্য বাজানো পরে যখন আমি লক্ষ্য করেছি যে, কিছু কিছু ক্ষেত্রে লেজ মাথা সামনে চলমান ছিল করুন ... কোন মধ্যবর্তী গ্যারান্টী আছে ক্রম headএবং tail\ ...: কমান্ড
জানুয়ারী

7
(sed -u 10q; echo ...; tail) < file.txt

থিমটিতে অন্য একটি ভিন্নতা (head;tail), তবে ছোট ফাইলগুলির জন্য প্রাথমিক বাফার ফিল ইস্যুটি এড়ানো।


4

head -10 file.txt; tail -10 file.txt

তা ছাড়া আপনার নিজের প্রোগ্রাম / স্ক্রিপ্ট লিখতে হবে।


1
সুন্দর, আমি সর্বদা ব্যবহার করেছি catএবং headবা tailপাইপ করেছি, আমি এগুলি পৃথকভাবে ব্যবহার করতে পারি তা জেনে রাখা ভাল!
পল

আমি কীভাবে এই প্রথম 10 + শেষ 10 টি অন্য কমান্ডে পাইপ করব?
টপ টপ

1
@ পল - 'আপনার_প্রগ্রাম' এর সাথে ডাব্লুসি-ল হিসাবে এটি 20 এর পরিবর্তে 10
ফেরায়

3
বা, একটি সাবশেল স্প্যান না করে: { head file; tail file; } | prog(ধনুর্বন্ধনী ভিতরে ফাঁকা, এবং পিছনের
অর্ধেকজন

1
বাহ ... প্রায় দুই বছর পরে অন্যের মতো উত্তর দেওয়ার (যদিও তাদের আগে টাইমস্ট্যাম্পযুক্ত) উত্তর পাওয়ার জন্য একটি ডাউন-ভোট, যে কারণে তারা কেন ভোট দিয়েছেন-কেন তা পোস্ট না করা পছন্দ করেছেন from নিস!
mah

4

জেএফ সেবাস্তিয়ান এর মন্তব্যের ভিত্তিতে :

cat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1

এই পদ্ধতিতে আপনি প্রথম লাইনে এবং বাকীগুলি আলাদা আলাদাভাবে একটি পাইপে প্রসেস করতে পারেন যা সিএসভি ডেটা নিয়ে কাজ করার জন্য দরকারী:

{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
এন * 2
2
4
6

3

এখানে সমস্যাটি হ'ল স্ট্রিম-ভিত্তিক প্রোগ্রামগুলি ফাইলের দৈর্ঘ্য আগেই জানে না (কারণ এটি যদি না হয় তবে এটি সত্যিকারের স্ট্রিম)।

tailশেষ এন লাইনগুলি দেখে বাফারের মতো সরঞ্জামগুলি এবং স্ট্রিমের শেষের জন্য অপেক্ষা করুন, তারপরে মুদ্রণ করুন।

যদি আপনি এটি একটি একক কমান্ডে করতে চান (এবং এটি কোনও অফসেটের সাথে কাজ করুন, এবং লাইনগুলি ওভারল্যাপ করে তবে তারা পুনরাবৃত্তি করবেন না) আমি আপনাকে উল্লিখিত আচরণটি অনুকরণ করতে হবে।

এই অদ্ভুত চেষ্টা করুন:

awk -v offset=10 '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile

অফসেট ফাইলের চেয়ে বড় হলে সমস্যাগুলি এড়ানোর জন্য এটি আরও কাজের প্রয়োজন
সমুস_

হ্যাঁ, এটি কেবল ফাইল নয়, পাইপযুক্ত আউটপুট নিয়ে কাজ করে: a.out | awk -v ...
ক্যামিল গডেসুন

প্রকৃতপক্ষে :) তবে এটি অবাস্তব স্বাভাবিক আচরণ, বেশিরভাগ কমান্ডলাইন প্রোগ্রাম স্টিডিনে কাজ করে যখন যুক্তি ছাড়াই ডাকে।
সামুস_

1
পছন্দসই আচরণের খুব কাছাকাছি তবে মনে হয় <10 লাইনের জন্য এটি অতিরিক্ত নতুন লাইন যুক্ত করে।
sorin

3

এই সমাধানটি শেষ হতে অনেক সময় নিয়েছিল যা কেবলমাত্র একমাত্র যা সমস্ত ব্যবহারের কেসকে আবৃত করে বলে মনে হয়েছে (এখন পর্যন্ত):

command | tee full.log | stdbuf -i0 -o0 -e0 awk -v offset=${MAX_LINES:-200} \
          '{
               if (NR <= offset) print;
               else {
                   a[NR] = $0;
                   delete a[NR-offset];
                   printf "." > "/dev/stderr"
                   }
           }
           END {
             print "" > "/dev/stderr";
             for(i=NR-offset+1 > offset ? NR-offset+1: offset+1 ;i<=NR;i++)
             { print a[i]}
           }'

বৈশিষ্টের তালিকা:

  • মাথার জন্য সরাসরি আউটপুট (স্পষ্টতই লেজের জন্য সম্ভব নয়)
  • বাহ্যিক ফাইলগুলির কোনও ব্যবহার নেই
  • MAX_LINES এর পরে প্রতিটি লাইনের জন্য একটি প্রগতিবার, দীর্ঘ চলমান কার্যের জন্য খুব দরকারী।
  • স্ট্যাডারে অগ্রগতি বার, এই আশ্বাস দিয়ে যে অগ্রগতি বিন্দুগুলি মাথা + লেজ থেকে আলাদা করা হয় (আপনি স্টাডাউট পাইপ করতে চাইলে খুব সহজ)
  • বাফারিংয়ের কারণে সম্ভাব্য ভুল লগিং অর্ডার এড়ানো (stdbuf)
  • সদৃশ + লেজের চেয়ে মোট রেখার সংখ্যা যখন ছোট হয় তখন আউটপুট সদৃশকরণ এড়ানো উচিত।

2

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

headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }' ; }

1

ভাল, আপনি সবসময় তাদের একসাথে চেইন করতে পারেন। ভালো লেগেছে head fiename_foo && tail filename_foo,। যদি এটি পর্যাপ্ত না হয় তবে আপনি নিজের প্রফাইলে ফাইল বা আপনি যে কোনও লগইন ফাইল ব্যবহার করেন তাতে নিজেকে বাশ ফাংশন লিখতে পারেন:

head_and_tail() {
    head $1 && tail $1
}

এবং, পরে এটি আপনার শেল প্রম্পট থেকে ডাকা: head_and_tail filename_foo


1

File.ext এর প্রথম 10 লাইন, তারপরে এর শেষ 10 লাইন:

cat file.ext | head -10 && cat file.ext | tail -10

ফাইলের শেষ 10 লাইন, তারপরে প্রথম 10:

cat file.ext | tail -10 && cat file.ext | head -10

তারপরে আপনি আউটপুটটি অন্য কোথাও পাইপ করতে পারেন:

(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program


5
আপনি যখন কেবল হেড -10 file.txt কল করতে পারেন তখন কেন বিড়াল ব্যবহার করবেন?
jstarek

আপনি কি লাইনের সংখ্যাকে পরিবর্তনশীল করতে পারেন, তাই কলটি এমন কিছু: হেড_ লেজ (ফু, এম, এন) - প্রথম এম ফেরত পাঠানোর শেষ এন লাইনগুলি?
রিচার্ডো

@ricardo যা ব্যাশ স্ক্রিপ্ট লেখার সাথে জড়িত যা এতে 3 টি আরোগুলি লাগে এবং এটিকে ওরফে- আইএন দিয়ে একটি ফাংশন tailএবং এগুলি পাস করে head
পল

1

আমি এটি করার জন্য একটি সাধারণ অজগর অ্যাপটি লিখেছিলাম: https://gist.github.com/garyvdm/9970522

এটি পাইপের (স্ট্রিম) পাশাপাশি ফাইলগুলি পরিচালনা করে।


2
কোডের সম্পর্কিত অংশগুলি পোস্ট করা ভাল।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

1

উপরের ধারণাগুলি আঁকুন (পরীক্ষিত বাশ & zsh)

তবে একটি উপনাম 'টুপি' হেড এবং লেজ ব্যবহার করছে

alias hat='(head -5 && echo "^^^------vvv" && tail -5) < '


hat large.sql

0

sedএই কাজের জন্য কেন ব্যবহার করবেন না ?

sed -n -e 1,+9p -e 190,+9p textfile.txt


3
এটি জ্ঞাত দৈর্ঘ্যের ফাইলগুলির জন্য কাজ করে তবে সেই ফাইলগুলির জন্য নয় যার দৈর্ঘ্য অজানা।
কেভিন

0

পাইপগুলি (স্ট্রিমগুলি) পাশাপাশি ফাইলগুলি পরিচালনা করতে, এটি আপনার .bashrc বা। প্রোফাইল ফাইলটিতে যুক্ত করুন:

headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' ; }

তাহলে আপনি পারবেন না শুধুমাত্র

headtail 10 < file.txt

কিন্তু

a.out | headtail 10

(10 টি যদি পুরানো পুরানো থেকে আলাদা 10 টি ইনপুটটির দৈর্ঘ্য ছাড়িয়ে যায় তবে এটি a.out | (head; tail)পূর্ববর্তী উত্তরদাতাদের ধন্যবাদ))

দ্রষ্টব্য: headtail 10না headtail -10


0

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

{ head; echo "####################\n...\n####################"; tail; } < file.txt

বা আপনি যদি 20 লাইন ছাড়া অন্য কোনও কিছু নিয়ে কাজ শুরু করেন তবে একটি লাইন গণনা এমনকি সহায়তা করতে পারে।

{ head -n 18; tail -n 14; } < file.txt | cat -n

0

কোনও ফাইলের প্রথম 10 এবং শেষ 10 লাইন মুদ্রণ করতে আপনি এটি ব্যবহার করতে পারেন:

cat <(head -n10 file.txt) <(tail -n10 file.txt) | less


0
sed -n "1,10p; $(( $(wc -l ${aFile} | grep -oE "^[[:digit:]]+")-9 )),\$p" "${aFile}"

দ্রষ্টব্য : এফাইল ভেরিয়েবলটিতে ফাইলের পুরো পথ থাকে


0

আমি বলব যে ফাইলের আকারের উপর নির্ভর করে সক্রিয়ভাবে এর বিষয়বস্তুগুলিতে পড়া বাঞ্ছনীয় নয়। এই পরিস্থিতিতে, আমি মনে করি কিছু সাধারণ শেল স্ক্রিপ্টিং যথেষ্ট হওয়া উচিত।

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

$ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done

এটি প্রতিটি ফাইলের প্রথম 10 লাইন এবং শেষ 10 লাইনগুলি মুদ্রণ করে এবং ফাইলের নাম এবং কিছু উপবৃত্তের আগে এবং পরেও মুদ্রণ করে।

একটি একক বৃহত ফাইলের জন্য, আপনি একই প্রভাবের জন্য কেবল নিম্নলিখিতটি চালাতে পারেন:

$ head somefile.csv && echo ... && tail somefile.csv

0

স্টিডিন গ্রহণ করে তবে সহজ এবং ব্যবহারের 99% ক্ষেত্রে কাজ করে

head_and_tail

#!/usr/bin/env bash
COUNT=${1:-10}
IT=$(cat /dev/stdin)
echo "$IT" | head -n$COUNT
echo "..."
echo "$IT" | tail -n$COUNT

উদাহরণ

$ seq 100 | head_and_tail 4
1
2
3
4
...
97
98
99
100
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.