লিনাক্স কমান্ড (বিড়ালের মতো) একটি নির্দিষ্ট পরিমাণের অক্ষর পড়তে


120

catলিনাক্সের মতো কোনও কমান্ড রয়েছে যা একটি ফাইল থেকে নির্দিষ্ট পরিমাণে অক্ষর ফিরিয়ে দিতে পারে?

যেমন আমার কাছে একটি টেক্সট ফাইল রয়েছে:

Hello world
this is the second line
this is the third line

এবং আমি এমন কিছু চাই যা প্রথম 5 টি অক্ষর ফেরত দেয় যা "হ্যালো" হবে।

ধন্যবাদ


নোট করুন যে প্রদত্ত উত্তরের কোনওটিই স্ট্রিম থেকে কেবলমাত্র এন বাইট গ্রহণ করে না। উদাহরণস্বরূপ: যা চিরতরে হারিয়ে যায় mkfifo /tmp/test.fifo; echo "hello world">/tmp/test.fifo & head -c 5 /tmp/test.fifoসেগুলিও গ্রহণ করে " world\n"
ইয়েতি

উত্তর:


192

head খুব কাজ করে:

head -c 100 file  # returns the first 100 bytes in the file

.. প্রথম 100 বাইট বের করুন এবং সেগুলি ফিরিয়ে আনব।

headএটির জন্য ব্যবহার সম্পর্কে কী দুর্দান্ত তা হল tailম্যাচের সিনট্যাক্স :

tail -c 100 file  # returns the last 100 bytes in the file

বাইটের রেঞ্জ পেতে আপনি এগুলি একত্রিত করতে পারেন। উদাহরণস্বরূপ, একটি ফাইল থেকে দ্বিতীয় 100 বাইট পেতে , প্রথম 200 টি পড়ুন headএবং শেষ 100 পেতে লেজ ব্যবহার করুন:

head -c 200 file | tail -c 100

@ মিফফাই: সাথে প্রথম 20 বাইটগুলি পড়ুন head, তারপরে tailশেষ 10 টি পেতে ব্যবহার করুন , যেমন:head -c 20 file | tail -c 10
ড্যান

47

আপনি বাইটের স্বেচ্ছাসেবী খণ্ডগুলি বের করতে ডিডি ব্যবহার করতে পারেন।

উদাহরণ স্বরূপ,

dd skip=1234 count=5 bs=1

এর ইনপুট থেকে তার আউটপুটে 1235 থেকে 1239 বাইট অনুলিপি করবে এবং বাকীটি ফেলে দেবে।

স্ট্যান্ডার্ড ইনপুট থেকে প্রথম পাঁচটি বাইট পেতে, করুন:

dd count=5 bs=1

মনে রাখবেন, আপনি যদি ইনপুট ফাইলের নামটি নির্দিষ্ট করতে চান তবে dd পুরানো ফ্যাশন যুক্তি পার্সিং করে থাকে, তাই আপনি এটি করবেন:

dd count=5 bs=1 if=filename

এটিও নোট করুন যে ডিডি শব্দবাচকভাবে এটি কী করেছিল তা ঘোষণা করে, যাতে তা টস করে, কর:

dd count=5 bs=1 2>&-

অথবা

dd count=5 bs=1 2>/dev/null

2
আমি সাধারণভাবে এই সমাধানটির বিরুদ্ধে সুপারিশ করব, কারণ dd bs=1একসাথে একক চরিত্র পড়তে এবং লিখতে বাধ্য করা ডিডি, যা headগণনা বড় হওয়ার চেয়ে ধীর গতিতে হয়। যদিও এটি গণনা = 5 এর জন্য লক্ষণীয় নয়।
প্রশংসনীয়

2
"ডিডি কাউন্ট = 1 বিএস = 5" সম্পর্কে কী? যে মাথা একযোগে পাঁচ বাইট পড়তে হবে। তবুও, মাথা সম্ভবত একটি পরিষ্কার সমাধান।
বেন Combee

1
এর জন্য ধন্যবাদ - আমি আসলে একটি বাইনারি ফাইল 'কাট' করার উপায় খুঁজছিলাম, এবং ddমনে হচ্ছে, কৌশলটি করবে .. চিয়ার্স!
sdaau

head -cdd bs=5 count=1
ব্যস্তবক্সে

11

মাথা :

নাম

মাথা - আউটপুট ফাইলের প্রথম অংশ

সংক্ষিপ্তসার

মাথা [ বিকল্প ] ... [ ফাইল ] ...

বিবরণ

স্ট্যান্ডার্ড আউটপুটে প্রতিটি ফাইলের প্রথম 10 টি লাইন মুদ্রণ করুন। একাধিক ফাইলের সাথে প্রতিটি ফাইলের নাম দেওয়ার আগে শিরোনাম। কোনও ফাইল না দিয়ে, বা যখন ফাইল থাকে - স্ট্যান্ডার্ড ইনপুট পড়ুন।

সংক্ষিপ্ত বিকল্পগুলির জন্য দীর্ঘ বিকল্পগুলিতে বাধ্যতামূলক যুক্তিগুলি বাধ্যতামূলক।
-c , --bytes = [-] N প্রতিটি ফাইলের প্রথম এন বাইট প্রিন্ট করে; শীর্ষস্থানীয় '-' দিয়ে, প্রতিটি ফাইলের শেষ এন বাইট ব্যতীত সমস্ত মুদ্রণ করুন


3

মাথা বা লেজ এছাড়াও এটি করতে পারে:

মাথা-সি এক্স

ফাইলের প্রথম এক্স বাইটগুলি মুদ্রণ করে (এটি কোনও ইউটিএফ -16 ফাইল হয় তবে অক্ষর নয়)। শেষ এক্স বাইট ব্যতীত লেজ একই কাজ করবে।

এটি (এবং কাটা) পোর্টেবল।


3
head -Line_number file_name | tail -1 |cut -c Num_of_chars

এই স্ক্রিপ্টটি নির্দিষ্ট লাইন এবং অবস্থান থেকে অক্ষরের সঠিক সংখ্যা দেয় যেমন:

head -5 tst.txt | tail -1 |cut -c 5-8

5 টি লাইনে অক্ষর দেয় এবং 5 নং লাইনের 5 থেকে 8 পর্যন্ত অক্ষর দেয়

দ্রষ্টব্য : tail -1মাথা দ্বারা প্রদর্শিত শেষ লাইনটি নির্বাচন করতে ব্যবহৃত হয়।


2

আপনি লাইনটি গ্রেপ করে ফেলতেও পারেন এবং উদাহরণস্বরূপ এটি কেটে ফেলতে পারেন:

grep 'পাঠ্য' ফাইলের নাম | কাটা-সি 1-5


যদি ইনপুট ফাইলটি কোনও with n এর অন্তহীন স্ট্রিম হয় তবে এটি কাজ করে না
অজয় ব্রহ্মক্ষত্রিয়

2

আমি জানি 6 বছর আগে জিজ্ঞাসা করা একটি প্রশ্নের জবাব উত্তর ...

তবে আমি কয়েক ঘন্টার জন্য অনুরূপ কিছু সন্ধান করছিলাম এবং পরে এটি সন্ধান করলাম: কাট-সি ঠিক এটি করে, একটি অতিরিক্ত বোনাস সহ যা আপনি একটি অফসেটও নির্দিষ্ট করতে পারেন।

কাট-সি 1-5 হ্যালো ফিরে আসবে এবং কাট-সি 7-11 বিশ্ব ফিরে আসবে । অন্য কোন আদেশের দরকার নেই


2
আপনার অধিকার!. আমি কেবলমাত্র আরও জেনেরিক একক কমান্ডের সম্ভাবনাটি হাইলাইট করতে চেয়েছিলাম যা কোনও ফাইলের মাঝামাঝি থেকে হেড-সি-এর বিপরীতে পাঠ্য ফেরত পাঠাতে পারে কেবল প্রারম্ভিক অক্ষরগুলি পড়বে, শেষ বর্ণগুলিতে লেজ রাখবে c এবং গ্রেপ ব্যবহার না করে :)।
ববিয়াস

2

যদিও এর জবাব বহু বছর আগে / গৃহীত হয়েছিল, বর্তমানে স্বীকৃত উত্তরটি কেবল আইসো -8859-1 এর মতো এক-বাইট-প্রতি-অক্ষর এনকোডিংয়ের জন্য, বা ভেরিয়েবল-বাইট অক্ষর সেটগুলির একক-বাইট সাবসেটের জন্য (ল্যাটিন অক্ষরের মতো) ইউটিএফ -8 এর মধ্যে)। এমনকি এর পরিবর্তে একাধিক-বাইট স্প্লাইস ব্যবহার করা কেবলমাত্র ইউটিএফ -16 এর মতো স্থির-মাল্টিবাইট এনকোডিংয়ের জন্য কাজ করবে। প্রদত্ত এখন হল UTF-8 একটি সার্বজনীন মান হচ্ছে, এবং যখন এ খুঁজছেন তার মত ভাল যে ভাষাভাষীর ভিত্তিতে করে ভাষাগুলি এই তালিকা এবং নেটিভ / মাধ্যমিক ব্যবহার দ্বারা 30 টি ভাষায় শীর্ষ এই তালিকা , এটি একটি বাতলান গুরুত্বপূর্ণ অক্ষর-শ্রেণীর ব্যবহার cut -cএবং tr/ sedসহ সাধারণ ভেরিয়েবল-বাইট অক্ষর-বান্ধব (বাইট ভিত্তিক নয়) কৌশল ।

বাইট বনাম অক্ষর সংক্রান্ত ইস্যু সম্পর্কিত দুটি সাধারণ লাতিন-কেন্দ্রিক ভুল / অনুমানের কারণে নিম্নলিখিতটি তুলনামূলকভাবে দ্বিগুণ ব্যর্থ হয়েছে ( headএকটিটির বনাম cut, অন্যটি [a-z][A-Z]বনাম [:upper:][:lower:]):

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     head -c 1 | \
$     sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]

এই (: FreeBSD 'র উপর এই কাজ জরিমানা, কিন্তু উভয় নোটটিতে cut& trগ্রিক জিএনইউ / লিনাক্স আমাকে যদিও জন্য হল UTF-8 এখনও mangled):

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     cut -c 1 | \
$     tr '[:upper:]' '[:lower:]'
π

আরও একটি সাম্প্রতিক উত্তর ইতিমধ্যে "কাটা" প্রস্তাব করেছিল, তবে কেবল পাশের ইস্যুতে যে এটি স্বেচ্ছাসেবক অফসেট নির্দিষ্ট করতে ব্যবহার করা যেতে পারে, সরাসরি প্রাসঙ্গিক চরিত্র বনাম বাইটস ইস্যুর কারণে নয়।

যদি আপনার cutহ্যান্ডেল নেই -cসঠিকভাবে পরিবর্তনশীল বাইট এনকোডিং সঙ্গে, "প্রথম Xঅক্ষর" (প্রতিস্থাপন Xআপনার নম্বর সহ) আপনি চেষ্টা করে দেখতে পারেন:

  • sed -E -e '1 s/^(.{X}).*$/\1/' -e q - যদিও এটি প্রথম লাইনে সীমাবদ্ধ
  • head -n 1 | grep -E -o '^.{X}' - যা প্রথম লাইনে সীমাবদ্ধ এবং যদিও দুটি কমান্ড চেইন করে
  • dd - যা ইতিমধ্যে অন্যান্য উত্তরে পরামর্শ দেওয়া হয়েছে, তবে এটি সত্যই জটিল
  • sedএকাধিক লাইনে ছড়িয়ে থাকা অক্ষরগুলি পরিচালনা করতে উইন্ডো বাফার সহচরী সহ একটি জটিল স্ক্রিপ্ট, তবে এটি সম্ভবত এমন কিছু ব্যবহার করার চেয়ে আরও জটিল / ভঙ্গুর isdd

যদি আপনার trভ্যারিয়েবল-বাইট এনকোডিং সহ অক্ষর-শ্রেণি সঠিকভাবে পরিচালনা না করে তবে আপনি চেষ্টা করতে পারেন:

  • sed -E -e 's/[[:upper:]]/\L&/g (গনুহ-নির্দিষ্ট)

দুঃখিত, তবে এটি এখানে কাজ করে না ... printf 'Πού ' | cut -c 1কেবল
জিব্রিশ

অন-লাইন ডকুমেন্টেশন অনুসারে, এটি এখনও উপলভ্য নয়: "কেবলমাত্র অক্ষর-তালিকায় তালিকাভুক্ত পজিশনে অক্ষরগুলি মুদ্রণের জন্য নির্বাচন করুন now আপাতত -b হিসাবে একই, তবে আন্তর্জাতিকীকরণ এটি পরিবর্তন করবে।" [ gnu.org/software/coreutils/manual/html_node/…
লিও

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

0

এখানে একটি সাধারণ স্ক্রিপ্ট যা ব্যবহার করে গুটিয়ে যায় dd এখানে উল্লিখিত পদ্ধতির :

extract_chars.sh

#!/usr/bin/env bash

function show_help()
{
  IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}

e.g. 

2 10 /tmp/it     => extract chars 2-10 from /tmp/it
EOF
  "
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`

if [ -z "$3" ]
then
  dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
  dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null 
fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.