Bunun bellekte yapmaktan daha iyi olmadığından emin değilim, ancak dosyasındaki her satır için dolgusunu ve giriş çizgileriyle eski alanı değiştiren bir borunun diğer tarafındaki sızıntısını ortaya sedçıkaran rbir 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'
ÇIKTI
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
Bunu başka bir şekilde yaptım. Bu saklamak yapar bazı : Bir dize gibi saklar - bellekte
"$1" -
... dosyadaki her satır için.
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"
}
Çok hızlı. Bu cat, dosyada satırlar olduğu kadar çok dosyadır |pipe. Borunun diğer tarafında bu giriş, dosyada satırlar olduğu kadar dosyanın kendisi ile birleştirilir.
case- malzeme sadece taşınabilirlik içindir yashve zshsüre, bölünmeye hem eklenti bir unsuru mkshve poshhem kaybetmek biri. ksh, dash, busyboxVe bashtarafından basılan olarak sıfır var gibi birçok alanda tam olarak dışarı bütün bölünmüş printf. Yukarıda yazıldığı gibi, makinemde yukarıda belirtilen mermilerin her biri için aynı sonuçları verir.
Dosya çok uzunsa, $ARGMAXçok fazla argümanla ilgili sorunlar olabilir , bu durumda da tanıtmanız xargsveya benzer olmanız gerekir .
Çıktı aynı olmadan önce kullanılan aynı girdi göz önüne alındığında. Ama daha büyük olsaydım ...
seq 10 10 10000 | nl -s, >/tmp/tmp
Bu, daha önce kullandığımla neredeyse aynı olan bir dosya oluşturur (sans 'Row') - ancak 1000 satırda. Ne kadar hızlı olduğunu kendiniz görebilirsiniz:
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 satırda, mermiler arasında performansta küçük bir değişiklik var - bashher zaman en yavaş olanı - ama yine de yaptıkları tek iş, arg dizesini (1000 kopya filename -) oluşturmak olduğu için, etki minimumdur. zshYukarıdaki gibi - ve arasındaki performans farkı bashburada saniyenin 100.'sidir.
İşte herhangi bir uzunlukta bir dosya için çalışması gereken başka bir sürüm:
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"
)
İlk argümanına /tmpyarı rastgele bir adla yumuşak bir bağlantı oluşturur, böylece garip dosya adlarına asılmayacaktır. Bu önemlidir çünkü cat'argümanları üzerinden bir boru üzerinden beslenir xargs. catbireyin çıkış kaydedilir <&3ise sed pbu dosyada hatları vardır kadar çok kez rints ilk parametre her çizgi - ve komut dosyası da bir boru aracılığı ile beslenmektedir. Yine pastegirişini birleştirir, ancak bu kez -standart girişi ve bağlantı adı için sadece iki argüman alır /dev/fd/3.
Bu son - /dev/fd/[num]bağlantı - herhangi bir linux sistemi ve daha birçok şey üzerinde çalışmalıdır, ancak bununla birlikte adlandırılmış bir boru oluşturmazsa mkfifove bunun yerine de kullanılmalıdır.
Yaptığı son şey, rmçıkmadan önce oluşturduğu yumuşak bağlantıdır.
Bu sürüm aslında hala sistemimde daha hızlı . Sanırım daha fazla uygulama yürütmesine rağmen, argümanlarını derhal vermeye başlar - oysa önce hepsini istiflemeden önce.
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