मैं नहीं कर रहा हूँ यकीन है कि यह स्मृति में यह कर की तुलना में बेहतर है, लेकिन एक साथ sed
कि r
इसके infile में हर पंक्ति और एक अन्य एक पाइप के दूसरे पक्ष पर के लिए अपने infile बाहर EADS बारी H
इनपुट लाइनों के साथ पुराने अंतरिक्ष ...
cat <<\IN >/tmp/tmp
Row1,10
Row2,20
Row3,30
Row4,40
IN
</tmp/tmp sed -e 'i\
' -e 'r /tmp/tmp' |
sed -n '/./!n;h;N;/\n$/D;G;s/\n/ /;P;D'
आउटपुट
Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row3,30 Row3,30
Row3,30 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40
मैंने यह दूसरा तरीका किया। यह मेमोरी में कुछ स्टोर करता है - यह एक स्ट्रिंग को स्टोर करता है जैसे:
"$1" -
... फ़ाइल में प्रत्येक पंक्ति के लिए।
pairs(){ [ -e "$1" ] || return
set -- "$1" "$(IFS=0 n=
case "${0%sh*}" in (ya|*s) n=-1;; (mk|po) n=+1;;esac
printf '"$1" - %s' $(printf "%.$(($(wc -l <"$1")$n))d" 0))"
eval "cat -- $2 </dev/null | paste -d ' \n' -- $2"
}
यह बहुत तेज़ है। यह cat
फ़ाइल के रूप में कई बार के रूप में फ़ाइल में लाइनें हैं |pipe
। पाइप के दूसरी तरफ उस इनपुट को फाइल के साथ मिला दिया जाता है, जितनी बार फाइल में लाइनें होती हैं।
case
- सामान बस पोर्टेबिलिटी के लिए है yash
और zsh
जबकि विभाजन करने के लिए दोनों ऐड एक तत्व, mksh
और posh
दोनों एक खो। ksh
, dash
, busybox
, और bash
वहाँ के रूप में शून्य के रूप में द्वारा मुद्रित कर रहे हैं कई क्षेत्रों के रूप में वास्तव में करने के लिए बाहर सभी विभाजित हो printf
। जैसा कि ऊपर लिखा गया है मेरी मशीन पर उपर्युक्त गोले में से हर एक के लिए समान परिणाम प्रस्तुत करता है।
यदि फ़ाइल बहुत लंबी है, तो $ARGMAX
बहुत सारे तर्कों के साथ समस्याएँ हो सकती हैं, जिस स्थिति में आपको परिचय xargs
या इसी तरह की आवश्यकता होगी ।
एक ही इनपुट को देखते हुए मैंने आउटपुट से पहले इस्तेमाल किया था। लेकिन, अगर मैं बड़ा होता ...
seq 10 10 10000 | nl -s, >/tmp/tmp
इससे पहले जो मैंने इस्तेमाल किया था ( लगभग 'पंक्ति') - लेकिन 1000 लाइनों पर एक समान फ़ाइल उत्पन्न करता है । आप खुद देख सकते हैं कि यह कितना तेज है:
time pairs /tmp/tmp |wc -l
1000000
pairs /tmp/tmp 0.20s user 0.07s system 110% cpu 0.239 total
wc -l 0.05s user 0.03s system 32% cpu 0.238 total
1000 लाइनों पर गोले के बीच प्रदर्शन में कुछ मामूली बदलाव होता है - bash
हमेशा की तरह सबसे धीमी - लेकिन क्योंकि वे जो भी काम करते हैं वह केवल arg string उत्पन्न करता है (1000 प्रतियाँ filename -
) प्रभाव कम से कम होता है। प्रदर्शन के बीच का अंतर zsh
- जैसा कि ऊपर है - और bash
यहां एक सेकंड का 100 वां है।
यहाँ एक और संस्करण है जो किसी भी लम्बाई की फ़ाइल के लिए काम करना चाहिए:
pairs2()( [ -e "$1" ] || exit
rpt() until [ "$((n+=1))" -gt "$1" ]
do printf %s\\n "$2"
done
[ -n "${1##*/*}" ] || cd -P -- "${1%/*}" || exit
: & set -- "$1" "/tmp/pairs$!.ln" "$(wc -l <"$1")"
ln -s "$PWD/${1##*/}" "$2" || exit
n=0 rpt "$3" "$2" | xargs cat | { exec 3<&0
n=0 rpt "$3" p | sed -nf - "$2" | paste - /dev/fd/3
}; rm "$2"
)
यह /tmp
अर्ध-यादृच्छिक नाम के साथ अपने पहले arg के लिए एक सॉफ्ट-लिंक बनाता है ताकि यह अजीब फ़ाइलनाम पर लटका हुआ न हो। यह महत्वपूर्ण है क्योंकि cat
एक पाइप पर इसके माध्यम से आर्ग को खिलाया जाता है xargs
। पहले आर्ग में हर लाइन को चिन्हित करते हुए cat
आउटपुट को सेव किया जाता है क्योंकि उस फाइल में कई बार लाइनें होती हैं - और इसकी स्क्रिप्ट को पाइप के जरिए भी फीड किया जाता है। फिर से इसके इनपुट को मिलाता है, लेकिन इस बार इसके मानक इनपुट और लिंक नाम के लिए केवल दो तर्क हैं ।<&3
sed
p
paste
-
/dev/fd/3
वह आखिरी - /dev/fd/[num]
लिंक - किसी भी लिनक्स सिस्टम पर काम करना चाहिए और इसके अलावा भी बहुत से काम करना चाहिए, लेकिन अगर वह नामांकित पाइप नहीं बनाता है mkfifo
और इसके बजाय इसका उपयोग करना चाहिए।
आखिरी चीज यह है rm
कि नरम-लिंक यह बाहर निकलने से पहले बनाता है।
यह संस्करण वास्तव में मेरे सिस्टम पर अभी भी तेज है। मुझे लगता है कि यह इसलिए है क्योंकि यह अधिक अनुप्रयोगों को निष्पादित करता है, यह उन्हें तुरंत अपने तर्क सौंपना शुरू कर देता है - जबकि इससे पहले कि यह उन सभी को ढेर कर देता है।
time pairs2 /tmp/tmp | wc -l
1000000
pairs2 /tmp/tmp 0.30s user 0.09s system 178% cpu 0.218 total
wc -l 0.03s user 0.02s system 26% cpu 0.218 total