我不确定如何在while循环中使用until循环。
我有一个500,000行的输入文件,如下所示:
#region MyRegion
#endregion
我希望实现的是按照数字顺序对第一列中的数字进行排序,这样我就可以将所有相似的行(例如,以相同数字开头的行)拉入新的文本文件{{1 }}。从那里我想按数字顺序排序第( 9 1 1 0.6132E+02
9 2 1 0.6314E+02
10 3 1 0.5874E+02
10 4 1 0.5266E+02
10 5 1 0.5571E+02
1 6 1 0.5004E+02
1 7 1 0.5450E+02
2 8 1 0.5696E+02
11 9 1 0.6369E+02
.....
)个文件的第四列。排序后,我想将每个已排序的"cluster${i}.txt"
文件的第一行写入单个输出文件中。 "cluster${i}.txt"
的示例输出是这样的:
"cluster${i}.txt"
以及如下所示的output.txt文件:
"cluster1.txt"
这是我写的:
1 6 1 0.5004E+02
1 7 1 0.5450E+02
1 11 1 0.6777E+02
....
答案 0 :(得分:3)
如果您的sort -n
知道如何处理指数表示法,则只需要一行:
sort -nk 1,4 <in.txt | awk '{ of="cluster" $1 ".txt"; print $0 >>of }'
...或者,也要将每个索引的第一行写为output.txt
:
sort -nk 1,4 <in.txt | awk '
{
if($1 != last) {
print $0 >"output.txt"
last=$1
}
of="cluster" $1 ".txt";
print $0 >of
}'
考虑使用awk
实现 - 例如GNU awk - 它将缓存文件描述符,而不是为每个附加重新打开每个输出文件;这将大大提高性能。
顺便说一句,让我们看一下原始剧本的错误:
很慢。真的,真的慢。
为每一行输入启动awk
20次的新实例(因为while read
的整点是迭代各行,所以将awk
放在while read
内1}}每行运行awk
至少一次)将对性能产生非常明显的影响。并不是说它实际上是这样做的,因为......
while read line
外循环正在从标准输入读取,而不是temp.txt
或input.txt
。
因此,如果stdin没有写任何内容,或者如果stdin指向没有像/dev/null
这样的内容的源,则该脚本根本不执行循环的内容。 / p>
line
。正在阅读line
,但temp.txt
正在进行操作。awk
实际上并不在内循环内,而是在外循环中,只是之前内循环。因此,对i
的值不同,它不会被运行20次,但每行读取只运行一次,而i
的值从之前执行的代码中遗留下来。[[foo]]
错了;它必须是[[ foo ]]
。To&#34; fix&#34;内部循环,做我想象你想写的东西,可能看起来像这样:
# this is slow and awful, but at least it'll work.
while IFS= read -r line; do
i=0
until [[ $i -ge 20 ]]; do
awk -v var="$i" '$1 == var' <<<"$line" >>"cluster${i}.txt"
i=$((i+1))
done
done <temp.txt
...或者,稍好一些(但仍然不如顶部建议的解决方案):
# this is a somewhat less awful.
for (( i=0; i<=20; i++ )); do
awk -v var="$i" '$1 == var' <temp.txt >"cluster${i}.txt"
head -n 1 "cluster${i}.txt"
done >output.txt
请注意,对于整个循环,只需对output.txt
重定向一次 - 这意味着我们只打开文件一次。