今天我已经在Stack Overflow上进行了大量的搜索,找到了解决这个问题的解决方案,并且在跳过X行之后发现了很多关于排序的问题,但是没有真正可靠的通用答案,所以我把自己的方法放在一起:
head -n 15 FILE.EXT > temp.txt
tail -n+16 FILE.EXT | sort >> temp.txt
mv temp.txt FILE.EXT
Run Code Online (Sandbox Code Playgroud)
这将对文件进行排序(选择排序选项),同时保留其前15行的顺序.这显然是相当不优雅的,有三个文件引用和两个不同的值要输入.理想情况下,如果可能的话,我想提出一个不那么繁琐的命令,因为这似乎是一个非常普遍的愿望而没有太多的支持.
我甚至不接近一个bash专家,所以我希望有一些bash-fu可以使这个快速的单行.有没有办法在单个命令中创建和引用变量,以便用户只需要输入名称和行号等内容?
这个'one-liner'生成输出:
awk 'NR <= 15 { print; next } { print | "sort" }'
Run Code Online (Sandbox Code Playgroud)
干净地覆盖原始文件更难,并且通常涉及写入临时文件并在完成时重命名的内容.
正如sputnick所 指出的,如果你有GNU awk,你可以使用该-i选项来就地覆盖:
gawk -i 'NR <= 15 { print; next } { print | "sort" }' FILE.EXT
Run Code Online (Sandbox Code Playgroud)
(并且gawk通常也安装为awk.)
如果你没有GNU awk,那么我有一个ow源自overwriteKernighan&Pike 的脚本的脚本UNIX编程环境就是这样做的.
用法:
ow FILE.EXT awk 'NR <= 15 { print; next } { print | "sort" }' FILE.EXT
Run Code Online (Sandbox Code Playgroud)
码:
: "@(#)$Id: ow.sh,v 1.6 2005/06/30 18:14:08 jleffler Exp $"
#
# Overwrite file
# From: The UNIX Programming Environment by Kernighan and Pike
# Amended: remove PATH setting; handle file names with blanks.
case $# in
0|1)
echo "Usage: $0 file command [arguments]" 1>&2
exit 1;;
esac
file="$1"
shift
new=${TMPDIR:-/tmp}/ovrwr.$$.1
old=${TMPDIR:-/tmp}/ovrwr.$$.2
trap "rm -f '$new' '$old' ; exit 1" 0 1 2 15
if "$@" >"$new"
then
cp "$file" "$old"
trap "" 1 2 15
cp "$new" "$file"
rm -f "$new" "$old"
trap 0
exit 0
else
echo "$0: $1 failed - $file unchanged" 1>&2
rm -f "$new" "$old"
trap 0
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
这是旧代码; 我现在已经修改了近十年,但我已经使用了很多.正如Charles Duffy所指出的,如果您可能面对以破折号开头的文件名(因为那些可能被误认为命令行选项或者),它可以做一些现代化,并且它应该有一个shebang线等.cpmv
它还显示了捕获信号(虽然现在,我通常陷阱' 0 1 2 3 13 15',相当于' EXIT HUP INT QUIT PIPE TERM')并命名临时文件以防止偶然干扰(使用$$而不是mktemp像我说的那样,它是旧代码).
| 归档时间: |
|
| 查看次数: |
57 次 |
| 最近记录: |