मैं नहीं कर रहा हूँ यकीन है कि यह स्मृति में यह कर की तुलना में बेहतर है, लेकिन एक साथ 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आउटपुट को सेव किया जाता है क्योंकि उस फाइल में कई बार लाइनें होती हैं - और इसकी स्क्रिप्ट को पाइप के जरिए भी फीड किया जाता है। फिर से इसके इनपुट को मिलाता है, लेकिन इस बार इसके मानक इनपुट और लिंक नाम के लिए केवल दो तर्क हैं ।<&3sed ppaste-/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