কোনও পাঠ্য ফাইলে কেবল প্রথম কলাম এবং শেষ কলামটি প্রদর্শন করতে শেল কমান্ডটি কীভাবে ব্যবহার করবেন?


30

টেক্সট ফাইলে কেবলমাত্র প্রথম কলাম এবং শেষ কলামটি দেখানোর জন্য সেড কমান্ডটি কীভাবে ব্যবহার করতে হয় তা নির্ধারণ করার জন্য আমার কিছু সহায়তা দরকার। আমি কলাম 1 এর জন্য এখনও অবধি যা করেছি তা এখানে:

cat logfile | sed 's/\|/ /'|awk '{print $1}'

শেষ কলামটি পাশাপাশি দেখাতে পাওয়ার জন্য আমার ব্যর্থ প্রচেষ্টা ছিল:

cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'

তবে এটি প্রথম কলাম এবং শেষ কলাম নেয় এবং এগুলি এক তালিকায় একত্রিত করে। প্রথম কলাম এবং শেষ কলামগুলি সেড এবং অ্যাজক কমান্ডের সাথে পরিষ্কারভাবে মুদ্রণের কোনও উপায় আছে কি?

নমুনা ইনপুট:

foo|dog|cat|mouse|lion|ox|tiger|bar

5
দয়া করে কিছু নমুনা ইনপুট সরবরাহ করুন।
জেসনওয়ারিয়ান

উত্তর:


51

প্রায় সেখানে. উভয় কলাম রেফারেন্স একে অপরের পাশে রাখুন।

cat logfile | sed 's/|/ /' | awk '{print $1, $8}'

এছাড়াও মনে রাখবেন যে আপনার catএখানে দরকার নেই।

sed 's/|/ /' logfile | awk '{print $1, $8}'

এছাড়াও নোট করুন যে আপনি awkকলাম বিভাজকগুলি |ফাঁকা পরিবর্তে বলতে পারেন , সুতরাং আপনার প্রয়োজন sedহয় না ।

awk -F '|' '{print $1, $8}' logfile

অনুযায়ী পরামর্শ দ্বারা কালেব , যদি আপনি একটি সমাধান এখনও গত ক্ষেত্র আউটপুট, এমনকি যদি সেখানে ঠিক আট নয় চান, আপনি ব্যবহার করতে পারেন $NF

awk -F '|' '{print $1, $NF}' logfile

এছাড়াও, যদি আপনি আউটপুটটি পৃথক পৃথক স্থানে রাখতে চান তবে |কোনও স্থান ব্যবহারের পরিবর্তে, আপনি আউটপুট ক্ষেত্রের বিভাজক নির্দিষ্ট করতে পারেন। দুর্ভাগ্যক্রমে, এটি কেবল -Fপতাকা ব্যবহারের চেয়ে কিছুটা বেশি আনাড়ি , তবে এখানে তিনটি পন্থা রয়েছে।

  • আপনি awkনিজেই ইনপুট এবং আউটপুট ফিল্ড বিভাজককে বিগইন ব্লকে নির্ধারণ করতে পারেন ।

    awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
  • পতাকাটির awkমাধ্যমে কমান্ড লাইন থেকে কল করার সময় আপনি এই ভেরিয়েবলগুলি বরাদ্দ করতে পারেন -v

    awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
  • বা সহজভাবে:

    awk -F '|' '{print $1 "|" $8}' logfile

4
এই সমস্যাটি কীভাবে সহজ করা যায় তা ভেঙে দেওয়া ভাল কাজ। আপনি |স্ট্রিং কনকেন্টেশনের জন্য ডিফল্ট স্থানের পরিবর্তে আউটপুট বিভাজক হিসাবে কীভাবে ব্যবহার করবেন সে সম্পর্কে একটি নোট যুক্ত করতে পারেন । এছাড়াও আপনি শেষ কলামটি পেতে $NFহার্ড কোডিংয়ের পরিবর্তে ব্যবহারের ব্যাখ্যা করতে পারেন $8
কালেব

12

|একটি |(বা আপনি যদি পছন্দ করেন তবে স্থান) দিয়ে কেবল প্রথম থেকে শেষ পর্যন্ত প্রতিস্থাপন করুন :

sed 's/|.*|/|/'

দ্রষ্টব্য যে কোনও sedবাস্তবায়ন নেই যেখানে |বিশেষ যেখানে রয়েছে (যতক্ষণ না বর্ধিত নিয়মিত অভিব্যক্তিগুলি কিছু বাস্তবায়নের মাধ্যমে -Eবা সক্ষম করা যায় না -r), \|নিজেই জিএনইউর মতো কিছু ক্ষেত্রেও বিশেষ sed। সুতরাং আপনি চরিত্রের সাথে মেলে এমনটি করার ইচ্ছা থাকলে আপনার এড়ানো উচিত নয়||

যদি স্থানটির সাথে প্রতিস্থাপন করা হয় এবং যদি ইনপুটটিতে ইতিমধ্যে কেবল একটির সাথে লাইন থাকতে পারে |, তবে আপনাকে সেটিকে বিশেষভাবে বিবেচনা করতে |.*|হবে যা সেগুলির সাথে মেলে না। এটি হতে পারে:

sed 's/|\(.*|\)\{0,1\}/ /'

(এটি .*|অংশটিকে alচ্ছিক করে তোলে ) বা:

sed 's/|.*|/ /;s/|/ /'

বা:

sed 's/\([^|]*\).*|/\1 /'

আপনি যদি ইনপুটটিতে ক্ষেত্রের সংখ্যা নির্বিশেষে প্রথম এবং অষ্টম ক্ষেত্র চান তবে এটি ঠিক:

cut -d'|' -f1,8


(সমস্ত ঐ (ইনপুট ফর্ম বৈধ পাঠ্য অভিমানী বিশেষ কোনো POSIX অনুবর্তী উপযোগ সঙ্গে কাজ করবে, sedবেশী হবে সাধারণত কাজ না হলে ইনপুট বাইট বা বাইট যে উদাহরণস্বরূপ মত বর্তমান লোকেলে বৈধ অক্ষর গঠন না ক্রমের হয়েছে printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'এ একটি ইউটিএফ -8 লোকেল))।


11

আপনি awkযেভাবেই ব্যবহার করছেন :

awk '{ print $1, $NF }' file

2
আপনার কি ইনপুট ফিল্ড বিভাজক (যেহেতু এটির চেয়ে |বরং সেই জায়গাটি মনে হয় ) -F\|বা এর সাথে একইরকম নির্দিষ্ট করার দরকার নেই? এছাড়াও যদি তিনি আউটপুট জন্য একই সীমানা ব্যবহার করতে চান?
কালেব

@ কালেব সম্ভবত: কর্মহীন উদাহরণের উপর ভিত্তি করে অনুমান করার চেষ্টা করার চেয়ে আমি ওপিটির ঠিক কী ইনপুটটি দেখতে পেল তা নিশ্চিত করার জন্য অপেক্ষা করছিলাম ...
জেসনওয়ারিয়ান

1
নোট করুন যে অনুমান করে ইনপুটটিতে কমপক্ষে 2 টি ক্ষেত্র রয়েছে।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলা ওপিতে কোডে স্পষ্টভাবে বলা হয়েছে যে এটির সর্বদা আটটি ক্ষেত্র রয়েছে।
michaelb958 - মনিকা

3
@ michaelb958 আমি মনে করি "স্পষ্টভাবে"
মামলাটিকে

4

আপনি যদি নিজেকে অজস্র এবং খুব কম বলে মনে করেন তবে আপনি একই জিনিস কোর্টিলগুলি দিয়ে অর্জন করতে পারেন:

paste <(           cut -d'|' -f1  file) \ 
      <(rev file | cut -d'|' -f1 | rev)

cutআপনি যখন প্রথম কলামটিতে কেবল আগ্রহী হন, বা যদি ডিলিমেটারগুলি স্থির হয় (যেমন স্পেসের পরিবর্তনশীল সংখ্যার নয়) তবে এটি ক্লাব এবং অ্যাডাব্লু / এসডের চেয়ে আরও কমপ্যাক্ট।
শ্রীধর সারনোবাত

2

দেখে মনে হচ্ছে আপনি পাঠ্যের প্রথম এবং শেষ ক্ষেত্রগুলি পাওয়ার চেষ্টা করছেন যা দ্বারা সীমিত করা আছে |

আমি ধরে নিয়েছি আপনার লগ ফাইলটিতে নীচের মতো পাঠ্য রয়েছে,

foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo

এবং আপনি যেমন আউটপুট চান,

foo bar
bar foo

যদি হ্যাঁ, তবে এখানে আসুন আপনার জন্য আদেশ

জিএনইউ সিডের মাধ্যমে,

sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file

উদাহরণ:

$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar

কলামগুলি পাইপ দ্বারা সীমাবদ্ধ নয় তবে সেগুলি কলামগুলিতে রয়েছে, আমি সেড ব্যবহার করতে আগ্রহী কিন্তু আপনার কমান্ডের মতো আপনার মতো করে অর্ডিক কমান্ডটি ব্যবহার করতে চাই না: সেড-আর এর ~ ^ ([^ |] *)। * \ | (। *) $ ~ \ 1 \ 2 ~ 'ফাইল
ব্যবহারকারী 70573

"কলামগুলি পাইপ দ্বারা সীমিত করা যায় না | তবে সেগুলি কলামগুলিতে থাকে", আপনার মানে কলামগুলি ফাঁকা জায়গা দ্বারা পৃথক করা হয়েছে?
অবিনাশ রাজ

একটি নমুনা ইনপুট এবং একটি আউটপুট ভাল হবে।
অবিনাশ রাজ

1

আপনার সম্ভবত এটি দিয়ে করা উচিত sed- আমি যাই হোক না কেন - তবে, কারণ এখনও কেউ এটিকে লিখেছেন:

while IFS=\| read col1 cols
do  printf %10s%-s\\n "$col1 |" " ${cols##*|}"
done <<\INPUT
foo|dog|cat|mouse|lion|ox|tiger|bar
INPUT

আউটপুট

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