लिनक्स कमांड एन फाइल को अपने आप में एन टाइम करने के लिए


31

मैंने प्रोजेक्ट गुटेनबर्ग (लगभग 0.5 एमबी) से एक सादा पाठ फ़ाइल पुस्तक ली है, जिसे मैं nएक बड़े पाठ फ़ाइल को उत्पन्न करने के लिए खुद को बार-बार संक्षिप्त करना चाहता हूं, जिस पर मैं कुछ एल्गोरिदम बेंचमार्क कर सकता हूं। क्या एक लिनक्स कमांड है जिसे मैं इसे प्राप्त करने के लिए उपयोग कर सकता हूं? catआदर्श लगता है, लेकिन अपने आप को एक फ़ाइल को व्यवस्थित करने के साथ बहुत अच्छा नहीं लगता है, साथ ही nसवाल के समय के हिस्से को सीधे संबोधित नहीं करता है ।


2
किसी प्रकार के लूप का उपयोग करें, और एपडिंग? इसलिए दोहराएं foo.txt >> bar.txt और इसे कुछ इस तरह से लपेटें कि कई बार कमांड चलेगी?
जर्नीमैन गीक

जवाबों:


35

इसके दो भाग, मेरे लिए - पहला - बिल्ली का उपयोग करने के लिए टेक्स्ट फ़ाइल को मानक आउटपुट में आउटपुट करने के लिए, और एक अन्य फ़ाइल में इसे जोड़ने के लिए ऐपेंड का उपयोग करने के लिए - जैसे foo.txt >> bar.txt, bar.txt में foo.txt को जोड़ देगा।

फिर इसे n बार के साथ चलाएं

for i in {1..n};do cat foo.txt >> bar.txt; done

अपने नंबर के साथ उस कमांड में n को प्रतिस्थापित करें

काम करना चाहिए, जहां n आपकी संख्या है

यदि आप csh का उपयोग करते हैं, तो 'रिपीट' कमांड है।

उत्तर के संबंधित भागों को यहां से कॉपी किया जाता है , और मैंने इसे डिफ़ॉल्ट बैश शेल पर एक ubuntu 11.04 सिस्टम पर परीक्षण किया।


3
मजेदार तथ्य: यह वास्तव में 'एन' की जगह के बिना काम करता है, जिस स्थिति में यह ASCII '1' और ASCII 'n' (इसलिए 62 बार) के बीच प्रत्येक वर्ण के लिए एक बार शरीर निष्पादित करेगा। लेकिन {1..12}सही ढंग से शरीर को 12 बार चलाएगा।
अर्नौट एंगेलन

1
आप प्रत्येक पुनरावृत्ति में संलग्न होने के बजाय पूरी पाइपलाइन को पुनर्निर्देशित करना चाह सकते हैं:for i in {1..n};do cat foo.txt; done > bar.txt
टोबी स्पाइट

2

मैं बोर हो गया हूँ इसलिए यहाँ कुछ और तरीके हैं कि कैसे किसी फाइल को अपने आप headमें सम्‍मिलित करें , अधिकतर एक बैसाखी के रूप में। मुझे क्षमा करें यदि मैं खुद को ओवरएक्सप्लेन करता हूं, तो मुझे सिर्फ बातें कहना पसंद है: पी


मान लें Nकि आप जो स्वयं करना चाहते हैं, उसकी संख्या और आपकी फ़ाइल का नाम है file

चर:

linecount=$(<file wc -l)

total_repeats=$(echo "2^$N - 1" | bc) # obtained through the power of MATH

total_lines=$((linecount*(total_repeats+1)))

tmp=$(mktemp --suffix .concat.self)

fileकहा जाता है की एक प्रति को देखते हुए file2, total_repeatsइसे बनाने के लिए कई बार fileजोड़ने की आवश्यकता होती है file2जैसे कि fileइसे स्वयं के Nसमय के लिए समाप्‍त किया गया था ।

कहा MATH यहाँ है, कम या ज्यादा: MATH (gist)

यह पहला सेमेस्टर कंप्यूटर विज्ञान सामान है, लेकिन यह एक समय हो गया है क्योंकि मैंने एक इंडक्शन प्रूफ किया है, इसलिए मैं इसे खत्म नहीं कर सकता ... (यह भी पुनरावृत्ति की यह कक्षा बहुत अच्छी तरह से ज्ञात है 2^Loopsइसलिए ऐसा भी है ...)


POSIX

मैं कुछ गैर-पॉज़िक्स चीजों का उपयोग करता हूं लेकिन वे आवश्यक नहीं हैं। मेरे उद्देश्यों के लिए:

 yes() { while true; do echo "$1"; done; }

ओह, मैंने केवल उसका उपयोग किया है। ओह ठीक है, अनुभाग यहाँ पहले से ही है ...


तरीके


head linecount ट्रैकिंग के साथ।

ln=$linecount
for i in $(seq 1 $N); do
    <file head -n $ln >> file;
    ln=$((ln*2))
done

कोई अस्थायी फ़ाइल, कोई बिल्ली नहीं, बहुत अधिक गणित अभी तक नहीं, सभी खुशी।


teeMATH के साथ

<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file

यहाँ teeसे पढ़ रहा है, fileलेकिन इसे हमेशा के लिए संलग्न है, इसलिए यह फ़ाइल को तब तक दोहराता रहेगा जब तक कि headयह बंद न हो जाए। और हम जानते हैं कि MATH के कारण इसे कब रोकना है । एप्लेटिंग के माध्यम से चला जाता है, इसलिए मैंने एक अस्थायी फ़ाइल का उपयोग किया। आप अतिरिक्त लाइनों को fileभी ट्रिम कर सकते हैं।


evalअंधेरे के स्वामी!

eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file

यह सिर्फ इसका विस्तार करता है cat file file file ...और इसे विकसित करता है। आप इसे $tmpफ़ाइल के बिना भी कर सकते हैं :

eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
  head -n $((total_lines-linecount)) >> file

इसके और लेखन ऑपरेशन के बीच में एक मध्यम आदमी डालकर दूसरा head"ट्रिक्स" cat। आप catदूसरे के साथ भी छल कर सकते हैं catलेकिन उसके साथ असंगत व्यवहार है। इसे इस्तेमाल करे:

test_double_cat() {
    local Expected=0
    local Got=0
    local R=0
    local file="$(mktemp --suffix .double.cat)"
    for i in $(seq 1 100); do

        printf "" > $file
        echo "1" >> $file
        echo "2" >> $file
        echo "3" >> $file

        Expected=$((3*$(<file wc -l)))

        cat $file $file | cat >> $file

        Got=$(<file wc -l)

        [ "$Expected" = "$Got" ] && R="$((R+1))"
    done
    echo "Got it right $R/100"
    rm $file
}

sed:

<file tr '\n' '\0' |
    sed -e "s/.*/$(yes '\0' | head -n $total_repeats | tr -d '\n')/g" |
        tr '\0' '\n' >> file

बल sedएक पंक्ति के रूप में पूरे फ़ाइल को पढ़ने में, यह के सभी कैप्चर, तो यह चिपकाता है $total_repeatsसमय की संख्या।

यदि आपकी फ़ाइल में कोई अशक्त अक्षर है तो यह निश्चित रूप से विफल हो जाएगा। जो आपको पता है उसे उठाएं।

find_missing_char() {
  local file="${1:-/dev/stdin}"

  firstbyte="$(<$file fold -w1 | od -An -tuC | sort -un | head -n 1)"
  if [ ! "$firstbyte" = "0" ]; then
    echo "\0"
  else
    printf "\\$(printf '%03o\t' $((firstbyte-1)) )"
  fi
}

यह सब अब के लिए है, मुझे आशा है कि यह मनमाना जवाब किसी को परेशान नहीं करेगा। मैंने उन सभी का कई बार परीक्षण किया लेकिन मैं केवल दो साल का शेल उपयोगकर्ता हूं इसलिए मुझे लगता है कि ध्यान रखें। अब सोने के लिए ...

rm $tmp


2

आप निश्चित रूप से इसके लिए उपयोग कर सकते हैं cat:

$ cat /tmp/f
foo
$ cat /tmp/foo /tmp/f
foo
foo

$nप्रतियां प्राप्त करने के लिए , आप yesपाइप का उपयोग कर सकते हैं head -n $n:

$ yes /tmp/f | head -n 10
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f

जो एक साथ देता है

yes /tmp/f | head -n $n | xargs cat >/tmp/output
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.