我不确定这是否比在内存中做的更好,但是它的作用是sed
使r
infile中的每一行都减少其infile,而在管道另一侧的另一行则使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
生成的文件几乎与我以前使用的文件相同(没有“ 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
始终是最慢的-但由于它们唯一要做的工作是生成arg字符串(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
的args通过管道通过管道馈入xargs
。cat
的输出被保存到<&3
同时sed
p
,因为有在该文件线路中的第一个参数的每一行rints多次-和它的脚本还经由配管供给到它。再次paste
合并其输入,但是这次仅-
再次为其标准输入和链接名称接受两个参数/dev/fd/3
。
最后一个- /dev/fd/[num]
链接-应该可以在任何linux系统上运行,并且还可以在更多其他系统上运行,但是,如果它不使用它创建命名管道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