_linc() ( ${sh-da}sh ${dbg+-vx} 4<&0 <&3 ) 3<<-ARGS 3<<\CMD
set -- $( [ $((i=${1%%*[!0-9]*}-1)) -gt 1 ] && {
shift && echo "\${inc=$i}" ; }
unset cmd ; [ $# -gt 0 ] || cmd='echo incr "#$((i=i+1))" ; cat'
printf '%s ' 'me=$$ ;' \
'_cmd() {' '${dbg+set -vx ;}' "$@" "$cmd" '
}' )
ARGS
s= ; sed -f - <<-INC /dev/fd/4 | . /dev/stdin
i_cmd <<"${s:=${me}SPLIT${me}}"
${inc:+$(printf '$!n\n%.0b' `seq $inc`)}
a$s
INC
CMD
Hàm trên sử dụng sed
để áp dụng danh sách đối số của nó dưới dạng chuỗi lệnh cho gia số dòng tùy ý. Các lệnh bạn chỉ định trên dòng lệnh được lấy nguồn từ hàm shell tạm thời được cung cấp tài liệu ở đây trên stdin bao gồm các dòng có giá trị từng bước tăng dần.
Bạn sử dụng nó như thế này:
time printf 'this is line #%d\n' `seq 1000` |
_linc 193 sed -e \$= -e r \- \| tail -n2
#output
193
this is line #193
193
this is line #386
193
this is line #579
193
this is line #772
193
this is line #965
35
this is line #1000
printf 'this is line #%d\n' `seq 1000` 0.00s user 0.00s system 0% cpu 0.004 total
Cơ chế ở đây rất đơn giản:
i_cmd <<"${s:=${me}SPLIT${me}}"
${inc:+$(printf '$!n\n%.0b' `seq $inc`)}
a$s
Đó là sed
kịch bản. Về cơ bản chúng tôi chỉ printf $increment * n;
. Vì vậy, nếu bạn đặt số gia của mình thành 100 printf
sẽ viết cho bạn một sed
tập lệnh chỉ gồm 100 dòng $!n
, một insert
dòng cho đầu cuối của tài liệu này và một dòngappend
dòng cho dòng dưới cùng - đó là nó. Hầu hết phần còn lại chỉ xử lý các tùy chọn.
Lệnh n
ext sed
sẽ in dòng hiện tại, xóa nó và kéo vào dòng tiếp theo. Các $!
chỉ định rằng nó chỉ nên thử trên bất kỳ dòng nào nhưng cuối cùng.
Chỉ được cung cấp một số gia tăng, nó sẽ:
printf 'this is line #%d\n' `seq 10` | ⏎
_linc 3
#output
incr #1
this is line #1
this is line #2
this is line #3
incr #2
this is line #4
this is line #5
this is line #6
incr #3
this is line #7
this is line #8
this is line #9
incr #4
this is line #10
Vì vậy, những gì xảy ra đằng sau hậu trường ở đây là chức năng được đặt thành bộ echo
đếm và cat
đầu vào của nó nếu không được cung cấp chuỗi lệnh. Nếu bạn thấy nó trên dòng lệnh, nó sẽ trông như sau:
{ echo "incr #$((i=i+1))" ; cat ; } <<HEREDOC
this is line #7
this is line #8
this is line #9
HEREDOC
Nó thực hiện một trong những điều này cho mỗi lần tăng. Nhìn:
printf 'this is line #%d\n' `seq 10` |
dbg= _linc 3
#output
set -- ${inc=2}
+ set -- 2
me=$$ ; _cmd() { ${dbg+set -vx ;} echo incr "#$((i=i+1))" ; cat
}
+ me=19396
s= ; sed -f - <<-INC /dev/fd/4 | . /dev/stdin
i_cmd <<"${s:=${me}SPLIT${me}}"
${inc:+$(printf '$!n\n%.0b' `seq $inc`)}
a$s
INC
+ s=
+ . /dev/stdin
+ seq 2
+ printf $!n\n%.0b 1 2
+ sed -f - /dev/fd/4
_cmd <<"19396SPLIT19396"
this is line #1
this is line #2
this is line #3
19396SPLIT19396
+ _cmd
+ set -vx ; echo incr #1
+ cat
this is line #1
this is line #2
this is line #3
_cmd <<"19396SPLIT19396"
RẤT NHANH
time yes | sed = | sed -n 'p;n' |
_linc 4000 'printf "current line and char count\n"
sed "1w /dev/fd/2" | wc -c
[ $((i=i+1)) -ge 5000 ] && kill "$me" || echo "$i"'
#OUTPUT
current line and char count
19992001
36000
4999
current line and char count
19996001
36000
current line and char count
[2] 17113 terminated yes |
17114 terminated sed = |
17115 terminated sed -n 'p;n'
yes 0.86s user 0.06s system 5% cpu 16.994 total
sed = 9.06s user 0.30s system 55% cpu 16.993 total
sed -n 'p;n' 7.68s user 0.38s system 47% cpu 16.992 total
Ở trên tôi nói với nó để tăng trên mỗi 4000 dòng. 17s sau và tôi đã xử lý 20 triệu dòng. Tất nhiên logic không nghiêm trọng ở đó - chúng tôi chỉ đọc mỗi dòng hai lần và đếm tất cả các ký tự của chúng, nhưng khả năng là khá mở. Ngoài ra, nếu bạn nhìn kỹ, bạn có thể nhận thấy rằng dường như các bộ lọc cung cấp đầu vào đang chiếm phần lớn thời gian.
BULK INSERT
? Tách dữ liệu khỏi câu lệnh SQL.