সাজান তবে শীর্ষে শিরোনাম লাইন রাখুন


55

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


1
আমি নীচের লিঙ্কটি জুড়ে এসেছি । তবে আমি { head -1; sort; }কাজ করার এই কৌশলটি পেতে পারি না । এটি সর্বদা প্রথম লাইনের পরে পাঠের একটি গোছা মুছে দেয়। কেউকি জানে এটা কেনো ঘটেছে?
jonderry

1
আমার সন্দেহ হয় কারণ headএটি একটি বাফারে একাধিক লাইন পড়ছে এবং এর বেশিরভাগ অংশ ফেলে দিচ্ছে। আমার sedধারণা একই সমস্যা ছিল।
অ্যান্ডি

@ জন্ডেরি - সেই কৌশলটি কেবল lseekসক্ষম ইনপুট দিয়ে কাজ করে যাতে পাইপ থেকে পড়ার সময় এটি কাজ করে না। আপনি যদি কোনও ফাইলে পুনর্নির্দেশ করেন >outfileএবং তারপরে চালান তবে এটি কাজ করবে{ head -n 1; sort; } <outfile
don_crissti

উত্তর:


58

অ্যান্ডির ধারণাটি চুরি করে এটিকে একটি ফাংশন তৈরি করে যাতে এটি ব্যবহার করা সহজ হয়:

# print the header (the first line of input)
# and then run the specified command on the body (the rest of the input)
# use it in a pipeline, e.g. ps | body grep somepattern
body() {
    IFS= read -r header
    printf '%s\n' "$header"
    "$@"
}

এখন আমি করতে পারি:

$ ps -o pid,comm | body sort -k2
  PID COMMAND
24759 bash
31276 bash
31032 less
31177 less
31020 man
31167 man
...

$ ps -o pid,comm | body grep less
  PID COMMAND
31032 less
31177 less

ps -C COMMANDএর চেয়ে বেশি উপযুক্ত হতে পারে grep COMMANDতবে এটি কেবল একটি উদাহরণ। এছাড়াও, আপনি -Cযদি অন্য একটি নির্বাচন বিকল্প ব্যবহার করেন তবে আপনি ব্যবহার করতে পারবেন না -U
মাইকেল

নাকি বলা উচিত body? হিসাবে body sortবা হিসাবে body grep। থটস?
মাইকেল

3
থেকে নতুন নামকরণ করা headerহয়েছে body, কারণ আপনি শরীরে ক্রিয়াটি করছেন। আশা করি এটি আরও বোধগম্য হয়।
মাইকেল

2
কল করতে মনে রাখুন bodyসব পরবর্তী পাইপলাইন অংশগ্রহণকারীদের উপর:ps -o pid,comm | body grep less | body sort -k1nr
বিশপ

1
@ টিম আপনি কেবল লিখতে পারেন <foo body sort -k2বা body sort -k2 <foo। আপনি যা চেয়েছিলেন তা থেকে কেবল একটি অতিরিক্ত চরিত্র।
মাইকেল

36

আপনি বাশ দিয়ে এইভাবে শীর্ষে রাখতে পারেন:

command | (read -r; printf "%s\n" "$REPLY"; sort)

বা পার্ল দিয়ে এটি করুন:

command | perl -e 'print scalar (<>); print sort { ... } <>'

2
+1 দুর্দান্ত। আমি মনে করি শেল ফাংশন হিসাবে বান্ডিলিং মূল্য।
মাইকেল

1
+1, কেন একটি সাবসেল পছন্দনীয়, বা এর {}পরিবর্তে ঠিক আছে ()?
jonderry

2
IFS=ইনপুট পড়ার সময় শব্দ বিভাজন অক্ষম করে। আমি পড়তে পড়তে এটি প্রয়োজনীয় মনে করি না $REPLY। সেট করা থাকলে (ডিফল্ট নয়) echoব্যাকস্ল্যাশ পলায়নের প্রসারিত করবে xpg_echo; printfসেক্ষেত্রে নিরাপদ। echo $REPLYউদ্ধৃতি ব্যতীত সাদা স্থান ঘনীভূত হবে; আমি মনে করি echo "$REPLY"ঠিক আছে। read -rযদি ইনপুটটিতে ব্যাকস্ল্যাশ পলায়ন থাকতে পারে তবে প্রয়োজনীয়। এর কয়েকটি ব্যাশ সংস্করণের উপর নির্ভর করে।
অ্যান্ডি

1
@ অ্যান্ডি: বাহ, আপনি ঠিক বলেছেন, read REPLY; echo $REPLY( আলাদা আলাদা স্পেসে স্ট্রিপগুলি) এবং read; echo $REPLY(না) এর জন্য বিভিন্ন বিধি ।
মিকেল

1
@ অ্যান্ডি: আইআইআরসি, এর ডিফল্ট মানটি xpg_echoআপনার সিস্টেমের উপর নির্ভর করে, যেমন সোলারিসের উপর আমি মনে করি এটির ক্ষেত্রে এটি ডিফল্ট। এই কারণেই গিলস printfএত পছন্দ করে : অনুমানযোগ্য আচরণের সাথে এটিই একমাত্র জিনিস।
মাইকেল

23

আমি একটি দুর্দান্ত awk সংস্করণ পেয়েছি যা স্ক্রিপ্টগুলিতে দুর্দান্তভাবে কাজ করে:

awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'

1
আমি এটি পছন্দ করি তবে এর কিছুটা ব্যাখ্যা দরকার - পাইপটি অ্যাজ্ক স্ক্রিপ্টের অভ্যন্তরে। ওটা কিভাবে কাজ করে? এটি কি sortবাহ্যিকভাবে আদেশটি কল করছে ? কেউ কি জেনার মধ্যে পাইপের ব্যবহার ব্যাখ্যা করে এমন কোনও পৃষ্ঠার লিঙ্কের কমপক্ষে জানেন?
ওয়াইল্ডকার্ড

@ উইল্ডকার্ড আপনি অফিসিয়াল ম্যানুয়াল পৃষ্ঠা বা এই প্রাইমারটি পরীক্ষা করতে পারেন ।
lapo

4

হ্যাকিশ তবে কার্যকর: বাছাইয়ের আগে 0সমস্ত শিরোনাম লাইন এবং 1অন্যান্য সমস্ত লাইনে প্রিপেন্ড করুন । বাছাইয়ের পরে প্রথম অক্ষরটি স্ট্রিপ করুন।

… |
awk '{print (NR <= 2 ? "0 " : "1 ") $0}' |
sort -k 1 -k… |
cut -b 3-

3

এখানে কিছু ম্যাজিক পার্ল লাইনের শব্দ রয়েছে যা আপনি নিজের আউটপুটটি সমস্ত কিছু সাজানোর জন্য পাইপ করতে পারেন তবে প্রথম লাইনটি শীর্ষে রাখুন: perl -e 'print scalar <>, sort <>;'


2

আমি command | {head -1; sort; }সমাধানটি চেষ্টা করেছিলাম এবং এটি নিশ্চিত করতে পারি যে এটি সত্যই জিনিসগুলিকে স্ক্রু আপ করে দিয়েছে - headপাইপ থেকে একাধিক লাইনে পড়ে, তারপরে কেবল প্রথমটি আউটপুট করে। আউটপুট, যে বাকি তাই head করা হয়নি পড়া, প্রেরণ করা sortআউটপুট লাইন 2 থেকে শুরু বাকি --NOT!

ফলাফলটি হ'ল আপনি লাইনগুলি (এবং একটি আংশিক লাইন!) অনুপস্থিত যা আপনার কমান্ড আউটপুটটির শুরুতে ছিল (আপনি যদি এখনও প্রথম লাইনটি বাদ দেন) - এমন একটি সত্য যা wcশেষে নিশ্চিতভাবে পাইপ যুক্ত করে নিশ্চিত করা যায় উপরের পাইপলাইন - তবে এটি যদি আপনি না জানেন তবে এটি সন্ধান করা অসাধারণ! এটি সমাধানের আগে আমার আউটপুটে কেন আংশিক লাইন (প্রথম 100 বাইট বা কাটা কাটা) ছিল তা চেষ্টা করার জন্য আমি কমপক্ষে 20 মিনিট সময় কাটিয়েছি।

আমি যে কাজটি শেষ করেছিলাম, যা সুন্দরভাবে কাজ করেছে এবং দু'বার কমান্ড চালানোর প্রয়োজন নেই, তা হ'ল:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile
sed 1d $myfile | sort

rm $myfile

যদি আপনাকে কোনও ফাইলে আউটপুট লাগানোর দরকার হয় তবে আপনি এটিকে এখানে পরিবর্তন করতে পারেন:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile > outputfile
sed 1d $myfile | sort >> outputfile

rm $myfile

আপনি ksh93 এর ব্যবহার করতে পারেন headbuiltin বা lineউপযোগ (সিস্টেমে এখনও আছে) অথবা gnu-sed -u qঅথবা IFS=read -r line; printf '%s\n' "$line", যে একটি সময়ে ইনপুট এক বাইট পড়া যে এড়ানো।
স্টাফেন চ্যাজেলাস

1

আমি মনে করি এটি সবচেয়ে সহজ।

ps -ef | ( head -n 1 ; sort )

অথবা এটি যা সম্ভবত দ্রুততর কারণ এটি একটি সাব শেল তৈরি করে না

ps -ef | { head -n 1 ; sort ; }

অন্যান্য শীতল ব্যবহার

শিরোনাম সারি পরে রেখা পরিবর্তন

cat file.txt |  ( head -n 1 ; shuf )

শিরোনাম সারি পরে রেখা বিপরীত

cat file.txt |  ( head -n 1 ; tac )

2
Unix.stackexchange.com/questions/11856/… দেখুন । এটি আসলে কোনও ভাল সমাধান নয়।
ওয়াইল্ডকার্ড

1
কাজ করছেন না, cat file | { head -n 1 ; sort ; } > file2কেবল মাথা দেখান
পিটার ক্রাউস

0
command | head -1; command | tail -n +2 | sort

4
এটি commandদু'বার শুরু হয় । সুতরাং এটি কিছু নির্দিষ্ট আদেশের মধ্যে সীমাবদ্ধ। তবে psউদাহরণ হিসাবে অনুরোধ করা কমান্ডের জন্য এটি কাজ করবে।
জোফেল

0

সরল ও সরল!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd ---> 'n' লাইন নং নির্দিষ্ট করে এবং 'd' মুছে ফেলার জন্য দাঁড়ায়।

1
জোফেল যেমন দেড় বছর আগে সরবার উত্তরে মন্তব্য করেছিলেন, এটি commandদু'বার শুরু হয়। পাইপলাইনে ব্যবহারের জন্য তাই উপযুক্ত নয়।
ওয়াইল্ডকার্ড

0

কমান্ডের সমাধান খুঁজতে আমি এখানে এসেছি w। এই কমান্ডটি কারা লগ ইন করেছে এবং তারা কী করছে তার বিশদ প্রদর্শন করে।

বাছাই করা ফলাফলগুলি দেখানোর জন্য, তবে শীর্ষে শীর্ষে রাখা শিরোনামগুলি (সেখানে শিরোনামগুলির 2 লাইন রয়েছে), আমি স্থির করেছিলাম:

w | head -n 2; w | tail -n +3 | sort

স্পষ্টতই এটি wদু'বার কমান্ড চালায় এবং তাই এটি সমস্ত পরিস্থিতিতে উপযুক্ত নাও হতে পারে। তবে এর সুবিধার জন্য এটি মনে রাখা যথেষ্ট সহজ।

মনে রাখবেন যে এর tail -n +3অর্থ 'তৃতীয় থেকে সমস্ত লাইন দেখান' (বিশদর man tailজন্য দেখুন)।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.