वर्णों की निर्दिष्ट मात्रा को पढ़ने के लिए लिनक्स कमांड (बिल्ली की तरह)


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 बाइट्स headप्राप्त करने के लिए, अंतिम 200 पाने के लिए पहले 200 को पढ़ें और पूंछ का उपयोग करें:

head -c 200 file | tail -c 100

@ मिफ़ी: पहले 20 बाइट्स के साथ पढ़ें head, फिर tailअंतिम 10 प्राप्त करने के लिए उपयोग करें, जैसे:head -c 20 file | tail -c 10
Dan

47

आप बाइट्स की मनमानी मात्रा को निकालने के लिए dd का उपयोग कर सकते हैं।

उदाहरण के लिए,

dd skip=1234 count=5 bs=1

इसके आउटपुट से इनपुट बाइट्स 1235 से 1239 तक कॉपी करेगा, और बाकी को छोड़ देगा।

मानक इनपुट से पहले पाँच बाइट्स प्राप्त करने के लिए, करें:

dd count=5 bs=1

ध्यान दें, यदि आप इनपुट फ़ाइल नाम निर्दिष्ट करना चाहते हैं, तो dd में पुराने जमाने का तर्क पार्सिंग है, इसलिए आप ऐसा करेंगे:

dd count=5 bs=1 if=filename

ध्यान दें कि dd शब्दशः घोषणा करता है कि उसने क्या किया है, इसलिए उसे दूर फेंकें, करें:

dd count=5 bs=1 2>&-

या

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

2
मैं इस समाधान के खिलाफ सामान्य रूप से सिफारिश करूंगा, क्योंकि dd bs=1बलों को एक समय में एक ही चरित्र को पढ़ने और लिखने की आवश्यकता होती है, जो कि headगिनती बड़ी होने की तुलना में बहुत धीमी है । यह गिनती = 5 के लिए ध्यान देने योग्य नहीं है, हालांकि।
अल्पकालिक

2
"Dd count = 1 bs = 5" के बारे में क्या? वह एक बार में पांच बाइट्स पढ़ेगा। फिर भी, सिर शायद एक स्पष्ट समाधान है।
बेन कॉम्पी

1
इसके लिए धन्यवाद - मैं वास्तव में एक द्विआधारी फ़ाइल को 'कट' करने का तरीका ढूंढ रहा था, और dd, ऐसा लगता है, यह चाल चलेगा .. चीयर्स!
सादाऊ

यह काम head -cकरने वाले dd bs=5 count=1दृष्टिकोण के बिना
व्यस्त बॉक्स पर एक लाइफसेवर था

11

सिर :

नाम

हेड - आउटपुट फाइल का पहला भाग

सार

सिर [ विकल्प ] ... [ फ़ाइल ] ...

विवरण

प्रत्येक FILE की पहली 10 पंक्तियों को मानक आउटपुट पर प्रिंट करें। एक से अधिक फ़ाइल के साथ, फ़ाइल नाम देने वाले शीर्षलेख के साथ प्रत्येक को पूर्ववर्ती करें। कोई फ़ाइल के साथ, या जब फ़ाइल है -, मानक इनपुट पढ़ें।

छोटे विकल्पों के लिए लंबे विकल्पों के लिए अनिवार्य तर्क अनिवार्य हैं।
-c , --bytes = [-] एन प्रत्येक फ़ाइल के पहले एन बाइट्स प्रिंट; अग्रणी '-' के साथ, प्रत्येक फ़ाइल के अंतिम लेकिन अंतिम बाइट्स को प्रिंट करें


3

सिर या पूंछ इसे भी कर सकती है:

हेड -सी एक्स

पहले X बाइट्स को प्रिंट करता है (जरूरी नहीं कि अगर यह UTF-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 के 8 से 5 अंक,

नोट : tail -1सिर द्वारा प्रदर्शित अंतिम पंक्ति का चयन करने के लिए उपयोग किया जाता है।


2

आप लाइन को बाहर निकाल सकते हैं और फिर इसे उदाहरण के लिए काट सकते हैं:

grep 'पाठ' फ़ाइल नाम | कट-सी 1-5


यह काम नहीं करता है यदि इनपुट फाइल no \ n के साथ एक अंतहीन स्ट्रीम है
Ajay Brahmakshatriya

2

मुझे पता है कि उत्तर 6 साल पहले पूछे गए एक प्रश्न के उत्तर में है ...

लेकिन मैं कुछ घंटों से कुछ ऐसी ही तलाश कर रहा था और तब पता चला कि: कट-सी बिल्कुल ऐसा ही है, एक अतिरिक्त बोनस के साथ जो आप एक ऑफसेट भी निर्दिष्ट कर सकते हैं।

cut -c 1-5 वापस आएगा हैलो और cut -c 7-11 वापस दुनिया में आ जाएगा । किसी अन्य कमांड की आवश्यकता नहीं है


2
आपका अधिकार!। मैं बस एक और अधिक सामान्य एकल कमांड की संभावना को उजागर करना चाहता था जो कि हेड -c के विपरीत एक फ़ाइल के बीच से पाठ को वापस कर सकता है-सिर्फ शुरुआती अक्षर पढ़ेगा, पिछले अक्षरों को -c। और बिना grep का उपयोग किए :)।
बॉबी

2

भले ही यह वर्षों पहले उत्तर / स्वीकार किया गया था, वर्तमान में स्वीकृत उत्तर केवल एक-बाइट-प्रति-वर्ण एन्कोडिंग जैसे कि iso-8859-1 के लिए, या चर-बाइट वर्ण सेट के एकल-बाइट सबसेट के लिए सही है (जैसे लैटिन वर्ण) UTF-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 में अभी भी घायल):

$ 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कई पंक्तियों में फैले हुए पात्रों को संभालने के लिए खिड़की के बफर के साथ एक जटिल स्क्रिप्ट, लेकिन यह शायद कुछ अधिक उपयोग करने की तुलना में अधिक बोझिल / नाजुक हैdd

यदि आपका trवर्ण वर्ण-वर्गों को चर-बाइट एन्कोडिंग के साथ सही ढंग से नहीं संभालता है, तो आप कोशिश कर सकते हैं:

  • sed -E -e 's/[[:upper:]]/\L&/g (जीएनयू विशेष)

क्षमा करें, लेकिन यह यहां काम नहीं करता है ... printf 'Πού ' | cut -c 1बस
जिबरिश

ऑन-लाइन प्रलेखन के अनुसार, यह अभी तक उपलब्ध नहीं है: "चरित्र-सूची में सूचीबद्ध पदों में केवल वर्णों को मुद्रित करने के लिए चयन करें। अभी के लिए -b जैसा ही है, लेकिन अंतर्राष्ट्रीयकरण इसे बदल देगा।" [ gnu.org/software/coreutils/manual/html_node/…
LEo

@ एलईओ अपनी दूसरी टिप्पणी में लिंक के आधार पर ऐसा लगता है कि आप एक जीएनयू आधारित ओएस का उपयोग कर रहे हैं, संभवतः जीएनयू / लिनक्स, इसलिए उस स्थिति में यह अपेक्षित है - मैं अपने जवाब के अंत में उल्लेख करता हूं। इसने तब काम किया (और अब मेरे लिए) FreeBSD पर काम करता है (और शायद कुछ अन्य OSes पर), लेकिन GNU / Linux पर काम नहीं किया (और अभी तक नहीं), उस स्थिति के लिए मैंने अंत में वैकल्पिक तरीकों का उल्लेख किया। मैं व्यक्तिगत रूप से तब तक इंतजार नहीं कर सकता जब तक कोई नहीं पाता है और जीएनयू टूलसेट के लिए आवश्यक अंतर्राष्ट्रीयकरण करने के लिए खाली समय और स्वयंसेवकों को काम करने के लिए आवश्यक है और उस संबंध में अन्य लोगों को भी।
रोवनथोरपे

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.