假设我有一个排序文件,名为sorted.txt,如下所示:
beautiful
easy
fast
functional
handy
现在,这样做echo fine-grained >> sorted.txt
会将“fine-grained”放在文件末尾的“handy”之后。有没有办法在“快速”和“功能”之间按顺序插入它,而不需要重新排序文件?
答案1
尽管理论上是可行的,但并没有一种神奇的方法可以做到这一点。
如果您确切知道要放置什么值,则可以使用sed
就地搜索和替换将新值粘贴到文件中,但考虑到排序的复杂性,基本上取决于您必须对其进行排序排长队的某个地方。
echo fine-grained >> sorted.txt
sort sorted.txt > sorted.txt.new && mv sorted.txt{.new,}
或者与sponge
:
{ echo fine-grained ; cat sorted.txt } | sort | sponge sorted.txt
编辑: 吉尔斯提出了一个很好的建议,即使用-m
排序参数来可能加快速度。从手册:
-m, --merge merge already sorted files; do not sort
这将阻止排序处理整个输入,它只需要扫描输入文件并找出它们之间的关系。
echo fine-grained | sort -m sorted.txt - | sponge sorted.txt
答案2
您无法在文件中插入数据 - POSIX API 中对此没有任何规定。您能做的最好的事情就是查找所有不移动的数据,写入新行,然后将所有后面的数据向下移动。如果不编写自己的程序,这将很棘手并且不容易完成。
如果您乐意生成新文件,awk 可以相当轻松地完成此操作:
awk -v newline=fine-grained '
!inserted && $0 > newline { print newline; inserted=1 }
1
'
仅当脚本尚未执行此操作并且输入行位于要插入的行之后时,脚本的第一行才会打印您要插入的行。它还记录了该行已插入。
第二行只是打印出输入行(表达式1
为true,默认操作是打印输入行,所以我们不需要说{ print }
。
答案3
你的问题的直接答案是否定的,你需要在某处运行某种类型的排序。
答案4
你必须通过某种方式来处理它,这只是时间问题。但我怀疑你正在寻找的是一次性交易。您的方法取决于您,并且有多种方法可能会更快。
这样就完成了工作,但也可以随意尝试其他方法。
echo "$(echo fine-grained | cat - sorted.txt | sort)" > sorted.txt
解构,从内部子 shell 开始,以避免在读取文件之前截断文件,将回显的输入与磁盘文件连接起来。呼应它引用的内容会保留换行符。然后排序。
sort -m
或者按照 Giles 的建议(并避免 UUOC)进行压缩。
echo "$(echo fine-grained | sort -m - sorted.txt)" > sorted.txt