कमांड को आउटपुट करने के लिए फ़ाइल सामग्री को कमांड करें?


28

मुझे पता है catकि यह कर सकते हैं, लेकिन इसका मुख्य उद्देश्य केवल सामग्री को प्रदर्शित करने के बजाय संक्षिप्त करना है।

मैं भी जानता हूं lessऔर more, लेकिन मैं कुछ सरल ( पेजर नहीं ) की तलाश कर रहा हूं, जो टर्मिनल पर एक फ़ाइल की सामग्री को आउटपुट करता है और यह विशेष रूप से इसके लिए बना है, अगर ऐसी कोई चीज है।


1
दरअसल 99% बार आप बिल्ली का उपयोग किसी भी चीज को छिपाने के बजाय फाइलों को प्रदर्शित करने के लिए करते हैं।
15

1
@LatinSuD - समय का 100% - संघनन cat
15

@ बाइक: यह एक ऑपरेशन करने से आपका क्या मतलब है; सामान्य भाषा का उपयोग यह होगा कि इसे कम से कम एक बार किया जाए। "मुद्रण" एक खाली स्ट्रिंग में किसी भी वर्ण को मुद्रित करना शामिल नहीं है; यह कहना उचित होगा कि यह कुछ भी नहीं छाप रहा है। अब कंप्यूटिंग a+b+cमें 2 अतिरिक्त प्रदर्शन शामिल हैं, और कंप्यूटिंग में aकुछ भी जोड़ना शामिल नहीं है। इसी तरह निष्पादित करने में cat fकुछ भी शामिल नहीं है (भले ही यह केवल एक चीज़ "एक फ़ाइल के अनुक्रम को संक्षिप्त करना" है)।
मार्क वैन लीउवेन

2
@mikeserv: मुझे वह नहीं मिलता है जिसका आप मतलब निकालते हैं। ज़रूर catएक फ़ाइल पढ़ता है और दूसरी फ़ाइल (स्ट्रीम) लिखता है, लेकिन इसका मतलब यह नहीं है कि यह कुछ भी समाप्‍त कर देता है। क्या आपको इसका मतलब हो सकता है कि cat fवास्तव में ऐसा कर रहे हैं cat - f, यह सिर्फ सच नहीं है।
मार्क वैन लीउवेन

1
@ उलझन 00: catवास्तव में संक्षिप्त करने के लिए थी ( cat file1 file2दोनों फाइलों को अलग करने के लिए संक्षिप्त करें)। लेकिन इसका साइड इफेक्ट यह है कि, जब केवल 1 फाइल को तर्क के रूप में रखा जाता है, तो यह उस फाइल को स्टैडआउट (जहां भी जाता है, या तो आपके टर्मिनल, या किसी चीज़ पर पुनर्निर्देशित करता है) को आउटपुट करता है। तो वहाँ कोई अन्य कमांड केवल उत्पादन करने के लिए बनाया गया था, जैसा कि catअस्तित्व में था और इसे बस अनुमति दी थी। इसलिए आप उपयोग करना चाहते हैं cat
ओलिवियर दुलैक

जवाबों:


37

सबसे स्पष्ट एक है cat। लेकिन, यह भी एक नज़र है headऔर tail। वहाँ भी अन्य खोल utillities लाइन द्वारा एक फ़ाइल लाइन मुद्रित करने के लिए कर रहे हैं: sed, awk, grep। लेकिन वे फ़ाइल सामग्री को वैकल्पिक करने या फ़ाइल के अंदर खोजने के लिए हैं।

मैंने अनुमान लगाने के लिए कुछ परीक्षण किए जो सबसे प्रभावी है। मैं straceयह देखने के लिए सभी गर्तों को चलाता हूं कि किसने सबसे कम सिस्टम कॉल किए। मेरी फाइल में 1275 लाइनें हैं।

  • awk: 1355 सिस्टम कॉल
  • cat: 51 सिस्टम कॉल
  • grep: 1337 सिस्टम कॉल
  • head: 93 सिस्टम कॉल
  • tail: 130 सिस्टम कॉल
  • sed: 1378 सिस्टम कॉल

जैसा कि आप देख सकते हैं, भले ही catफ़ाइलों को संक्षिप्त करने के लिए डिज़ाइन किया गया था, यह सबसे तेज़ और सबसे प्रभावी है। sed, awkऔर grepफ़ाइल लाइन को लाइन से प्रिंट किया, यही कारण है कि उनके पास 1275 से अधिक कॉल हैं।


8
Syscalls की गिनती करने के लिए अच्छा विचार है!
Jan

1
+1, उत्तर अधिक सटीक है (बिल्ली के अर्थ के बारे में), अधिक पूर्ण (विकल्प), और शोधित (syscalls)
ओलिवियर

23

मुझे पता है catकि यह कर सकते हैं, लेकिन इसका मुख्य उद्देश्य केवल सामग्री को प्रदर्शित करने के बजाय संक्षिप्त करना है।

इसका उद्देश्य catयह है कि, स्टडआउट के लिए एक फ़ाइल और आउटपुट पढ़ें।


1
लेकिन cat --helpकहते हैं "कॉनसैटनेट फ़ील (एस), या मानक इनपुट, मानक आउटपुट के लिए"। मैं कुछ भी नहीं चाहता
उलझन में

18
मानो या न मानो, बिल्ली बिल्कुल वही है जो आप वैसे भी देख रहे हैं।
Jan

5
नहीं, @ भ्रमित00, जन अधिकार। बात यह है - टर्मिनल है stdout - आप देखते हैं? ऐसा readlink /dev/fd/1उदाहरण के लिए - तुम वहाँ में अपने tty का नाम मिलना चाहिए अगर एक मानक प्रॉम्प्ट पर चल रहा है। आउटपुट को इनपुट करने के लिए आप क्या करने के लिए कह रहे हैं।
12

2
@ मोटरसाइकल हाँ, मैं आपकी बात देख रहा हूँ, मुझे लगता है कि मैं भी 'कॉन्फेटनेट' अर्थ पर नियत था।
उलझन में

3
तर्क यह है, एक फ़ाइल की सामग्री को प्रिंट करना अनुक्रम में एक या एक से अधिक फ़ाइलों की सामग्री को मुद्रित करने का एक विशेष मामला है ।
zwol

10

सबसे पहले, catमानक आउटपुट को लिखते हैं, जो जरूरी नहीं कि एक टर्मिनल है, भले ही catएक कमांड के रूप में एक इंटरैक्टिव शेल में टाइप किया गया हो। यदि मानक मानक पुनर्निर्देशित होने पर भी आपको टर्मिनल पर लिखने के लिए कुछ चाहिए, तो यह इतना आसान नहीं है (आपको यह निर्दिष्ट करने की आवश्यकता है कि कौन सी टर्मिनल है, और एक स्क्रिप्ट से कमांड निष्पादित होने पर एक भी नहीं हो सकता है), हालांकि एक अगर कमांड केवल एक पाइप लाइन का एक हिस्सा है, तो (ab) मानक त्रुटि आउटपुट का उपयोग कर सकता है। लेकिन जब से आपने संकेत दिया कि catवास्तव में काम करता है, मुझे लगता है कि आप ऐसी स्थिति के बारे में नहीं पूछ रहे थे।

यदि आपका उद्देश्य मानक आउटपुट में लिखे गए को एक पाइपलाइन में भेजने का था, तो उपयोग catकरना बिल्ली के लिए बेकार उपयोग के योग्य होगा , क्योंकि cat file | pipeline(जहां pipelineकिसी भी पाइपलाइन के लिए खड़ा है) को अधिक कुशलता से किया जा सकता है <file pipeline। लेकिन फिर, आपके शब्दों से मैं यह कहता हूं कि यह आपका इरादा नहीं था।

इसलिए यह इतना स्पष्ट नहीं है कि आप किस बारे में चिंता कर रहे हैं। यदि आप catटाइप करने के लिए बहुत लंबे समय तक पाते हैं, तो आप एक या दो-चरित्र उर्फ ​​को परिभाषित कर सकते हैं (अभी भी कुछ ऐसे नाम हैं जो मानक यूनिक्स में अप्रयुक्त रहते हैं)। यदि आप चिंता कर रहे हैं कि catबेकार चक्र खर्च कर रहे हैं , तो आपको नहीं करना चाहिए।

यदि कोई ऐसा कार्यक्रम था nullजो कोई तर्क नहीं लेता है और बस मानक इनपुट को मानक आउटपुट (पाइपलाइनों के लिए तटस्थ वस्तु) की प्रतिलिपि बनाता है, तो आप वह कर सकते हैं जो आप चाहते हैं <file null। ऐसा कोई कार्यक्रम नहीं है, हालांकि यह लिखना आसान होगा (केवल एक-लाइन mainफ़ंक्शन के साथ एक सी प्रोग्राम काम कर सकता है), लेकिन catबिना तर्कों के कॉल करना (या cat -यदि आप स्पष्ट होना पसंद करते हैं) तो बस यही करता है।

यदि कोई ऐसा nocatकार्यक्रम था जो बिल्कुल एक फ़ाइल नाम तर्क लेता है, तो फ़ाइल को खोलने की कोशिश करता है, अगर यह नहीं हो सकता है, तो इसकी शिकायत करता है, और अन्यथा फ़ाइल से मानक आउटपुट पर कॉपी करने के लिए आगे बढ़ता है, तो यह वही होगा जो आप पूछ रहे हैं। यह लिखने की तुलना में केवल थोड़ा कठिन है null, मुख्य कार्य फ़ाइल खोलना, परीक्षण करना, और संभवतः शिकायत करना (यदि आप सावधानीपूर्वक हैं, तो आप एक परीक्षण भी शामिल करना चाह सकते हैं कि एक तर्क है, और अन्यथा शिकायत करें)। लेकिन फिर cat, अब एक ही तर्क के साथ प्रदान किया जाता है, बस यही करता है, इसलिए किसी भी nocatकार्यक्रम की कोई आवश्यकता नहीं है ।

एक बार जब आप nocatप्रोग्राम लिखने में सफल हो गए , तो एक ही तर्क पर क्यों रुकें? कोड को एक लूप में लपेटना for(;*argp!=NULL;++argp)वास्तव में कोई प्रयास नहीं है, बाइनरी में मशीन के अधिकांश निर्देशों को जोड़ता है, और गलत संख्या के तर्कों के बारे में शिकायत करने से बचता है (जो कई और निर्देशों को बख्शता है)। Voilà का एक आदिम संस्‍करण cat, सम्‍मिलित फ़ाइलें। (ईमानदार होने के लिए आपको इसे थोड़ा मोड़ने की ज़रूरत है ताकि तर्क के बिना यह व्यवहार करे null।)

निश्चित रूप से वास्तविक catकार्यक्रम में, उन्होंने कुछ घंटियाँ और सीटी जोड़ीं, क्योंकि वे हमेशा करते हैं। लेकिन सार यह है कि catलागत का "संक्षिप्त" पहलू वास्तव में न तो किसी भी कार्यक्रम के लिए, न ही प्रोग्रामर के लिए और न ही मशीन के निष्पादन के लिए है। तथ्य यह है कि इस तरह के कार्यक्रमों के अस्तित्व को catसमझा nullऔर nocatसमझाता है। catयदि परिणाम पाइपलाइन में जाता है, तो एक ही तर्क के साथ उपयोग करने से बचें , लेकिन अगर यह टर्मिनल पर फ़ाइल सामग्री को प्रदर्शित करने के लिए उपयोग किया जाता है, तो यहां तक ​​कि पृष्ठ जो मैं मानता हूं कि यह उपयोगी उपयोग है cat, इसलिए संकोच न करें।


आप परीक्षण कर सकते हैं जो catवास्तव में एक हाइपरथेटिक nocatकार्यक्षमता के चारों ओर एक सरल लूप द्वारा लागू किया गया है , catजिसमें कई फ़ाइल नामों के साथ कॉल करके, जिनके बीच एक अमान्य नाम है, पहली स्थिति में नहीं: तुरंत शिकायत करने के बजाय कि यह फ़ाइल मौजूद नहीं है, catपहले पूर्ववर्ती को डंप करता है मान्य फ़ाइलें, और फिर अमान्य फ़ाइल के बारे में शिकायत करता है (कम से कम मेरी बिल्ली कैसे व्यवहार करती है)।


7

zshकोशिश के तहत

<file

मेरा मानना ​​है कि यह फाइल प्रिंट करने का सबसे छोटा तरीका है। यह 'छिपी' cat(या moreअगर स्टडआउट एक टर्मिनल है) का उपयोग करता है, लेकिन मुद्रण के लिए उपयोग की जाने वाली कमांड को READNULLCMDचर द्वारा नियंत्रित किया जाता है जिसे आप सीधे कमांड नाम या यहां तक ​​कि किसी फ़ंक्शन द्वारा सीधे अधिलेखित कर सकते हैं। उदाहरण के लिए लाइन नंबरिंग के साथ फाइल प्रिंट करना:

numcat() { nl -s'> ' -w2 - }
READNULLCMD=numcat
<file

5

POSIX परिभाषित बिल्ली के रूप में:

नाम

बिल्ली - समवर्ती और प्रिंट फाइलें

SYNOPSIS

बिल्ली [-यू] [फ़ाइल ...]

विवरण

बिल्ली उपयोगिता अनुक्रम में फाइलें पढ़ेगी और उसी क्रम में मानक आउटपुट के लिए अपनी सामग्री लिखेंगे।

तो मुझे लगता है कि यहाँ संक्षिप्त का अर्थ है अनुक्रम में फ़ाइलें पढ़ें


5

मुझे पता है कि यह एक भूतकाल का प्रश्न है। तकनीकी रूप से, चूंकि किसी फ़ाइल की सामग्री को मुद्रित stdoutकरना संक्षिप्त रूप का एक रूप है, catशब्दार्थ रूप से उपयुक्त है। यह मत भूलिए कि printfडेटा को प्रारूपित करने और प्रिंट करने का शब्दार्थ है। बैश फ़ाइलों से पुनर्निर्देशित इनपुट और आउटपुट को सिंटैक्स भी प्रदान करता है। इनका एक संयोजन इसका उत्पादन कर सकता है:

printf '%s' "$(<file.txt)"

4
विशेष रूप से राउंडअबाउट होने के अलावा, प्रदर्शित कमांड के बराबर नहीं है cat file.txt, क्योंकि यह किसी भी नई रूपरेखा (ऐसा $(...)करता है) को हटा देगा ।
मार्क वैन लीउवेन

+1, अच्छा कैच। वह नहीं जानता था।
जेम्स एम। ले।

3

bashबिल्डिंस का उपयोग करना और उपप्रकार निर्माण से बचना:

{ while IFS='' read -rd '' _bcat_; do printf '%s\0' "${_bcat_}"; done; printf '%s' "${_bcat_}"; unset _bcat_; } <'/path/to/file'

IFSकेवल readआदेश पर लागू किया जाएगा , इसलिए अपने वैश्विक IFSपरिवर्तनों के बारे में चिंता न करें ।

लूप को अशक्त पात्रों को संभालने के लिए आवश्यक है (स्टीफन चेज़लस के लिए धन्यवाद)।

यह तरीका बड़ी फ़ाइलों के लिए उपयुक्त नहीं है क्योंकि फ़ाइल सामग्री पहले चर (इसलिए मेमोरी) में पढ़ी जाती है। BTW मैंने 39M टेक्स्ट फाइल को इस तरह से प्रिंट करने की कोशिश की है और मेमोरी उपयोग को 5M से अधिक नहीं किया है, इसलिए इस मामले के बारे में निश्चित नहीं है।

यह धीमा और सीपीयू अक्षम भी है: उसी 39 एम फ़ाइल के लिए सिंगल कोर के 100% उपयोग के साथ ~ 3 मिनट लगते हैं।

बड़ी फ़ाइलों या बायनेरी के लिए बेहतर उपयोग करना cat '/path/to/file'या dd if='/path/to/file' bs=1Mयदि संभव हो तो।


1
यह भी देखें pv -qकि लिनक्स पर कौन सा उपयोग कर सकते हैं splice()जो कुछ प्रकार के स्टड / स्टडआउट के प्रदर्शन में सुधार करेगा।
स्टीफन चेजलस

1

बस एक प्रदर्शन के रूप में, आप कर सकते हैं

cp foo /dev/stdout
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.