나는 확실히이 메모리에하는 것보다 더 나은,하지만하지있어 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
그러면 이전에 사용한 것과 거의 동일한 파일 (sans 'Row')이 생성 되지만 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
항상 느리지 만-어쨌든 그들이하는 유일한 작업은 인수 문자열 (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
이상한 파일 이름에 걸리지 않도록 세미 임의 이름 으로 첫 번째 인수에 대한 소프트 링크를 만듭니다 . 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