我有我想要使用UNIX(Cygwin的,在我的情况)排序实用程序排序固定宽度字段文件。
问题是存在于正被分类到的文件的底部(如每首标线以冒号开始)的文件的顶部两行头。
有没有办法要么告诉排序“通过跨排序,则前两行”或指定排序结肠线顶端排序 - 其余的行总是以6位数字开始(这实际上是关键我“M排序上)是否有帮助。
例:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00
会排到:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile
括号创建一个子shell,结束了标准输出,所以你可以把它管道或重定向它,就好像它来自一个命令。
如果你不介意使用awk
,你可以利用awk
的内置管能力
例如。
extract_data | awk 'NR<3{print $0;next}{print $0| "sort -r"}'
这将打印逐字前两行和管道通过,其余sort
。
请注意,这具有能够选择性地传送输入的部分排序非常特殊的优势。 所有其他方法建议可多次读取只会那种纯文本文件。 这适用于任何东西。
下面是关于管道的数据兼容版本:
(read -r; printf "%s\n" "$REPLY"; sort)
如果你的头有多条线路:
(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)
该解决方案是从这里
您可以使用tail -n +3 <file> | sort ...
tail -n +3 <file> | sort ...
(尾将输出从第三行的文件内容)。
head -2 <your_file> && nawk 'NR>2' <your_file> | sort
例:
> cat temp
10
8
1
2
3
4
5
> head -2 temp && nawk 'NR>2' temp | sort -r
10
8
5
4
3
2
1
只需要2行代码...
head -1 test.txt > a.tmp;
tail -n+2 test.txt | sort -n >> a.tmp;
对于数字数据,需要-n。 对于阿尔法排序,则不需要-n。
示例文件:
$猫的test.txt
头
8
五
100
1
-1
结果:
$猫a.tmp
头
-1
1
五
8
100
所以这里有一个bash函数,其中参数是完全一样的排序。 支持文件和管道。
function skip_header_sort() {
if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
local file=${@: -1}
set -- "${@:1:$(($#-1))}"
fi
awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
}
这个怎么运作。 此行检查,如果有至少一个参数,如果最后一个参数是一个文件。
if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
此文件保存到单独的参数。 因为我们将要删除的最后一个参数。
local file=${@: -1}
在这里,我们删除了最后一个参数。 因为我们不想把它作为一个类的说法。
set -- "${@:1:$(($#-1))}"
最后,我们做的awk部分,传递的参数(减去最后一个参数如果是文件)中awk来排序。 这是orignally由Dave建议和修改,以排序参数。 我们依靠的事实是$file
将是空的,如果我们的管道,从而忽略。
awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
示例用法用逗号分隔的文件。
$ cat /tmp/test
A,B,C
0,1,2
1,2,0
2,0,1
# SORT NUMERICALLY SECOND COLUMN
$ skip_header_sort -t, -nk2 /tmp/test
A,B,C
2,0,1
0,1,2
1,2,0
# SORT REVERSE NUMERICALLY THIRD COLUMN
$ cat /tmp/test | skip_header_sort -t, -nrk3
A,B,C
0,1,2
2,0,1
1,2,0
与Python:
import sys
HEADER_ROWS=2
for _ in range(HEADER_ROWS):
sys.stdout.write(next(sys.stdin))
for row in sorted(sys.stdin):
sys.stdout.write(row)
下面是从其他的答案得出的bash shell的功能。 它可以处理文件和管道。 第一个参数是文件名或“ - ”为标准输入。 其余的参数传递给排序。 几个例子:
$ hsort myfile.txt
$ head -n 100 myfile.txt | hsort -
$ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r
Shell函数:
hsort ()
{
if [ "$1" == "-h" ]; then
echo "Sort a file or standard input, treating the first line as a header.";
echo "The first argument is the file or '-' for standard input. Additional";
echo "arguments to sort follow the first argument, including other files.";
echo "File syntax : $ hsort file [sort-options] [file...]";
echo "STDIN syntax: $ hsort - [sort-options] [file...]";
return 0;
elif [ -f "$1" ]; then
local file=$1;
shift;
(head -n 1 $file && tail -n +2 $file | sort $*);
elif [ "$1" == "-" ]; then
shift;
(read -r; printf "%s\n" "$REPLY"; sort $*);
else
>&2 echo "Error. File not found: $1";
>&2 echo "Use either 'hsort <file> [sort-options]' or 'hsort - [sort-options]'";
return 1 ;
fi
}
这是一样的伊恩Sherbin的答案,但我的实现是: -
cut -d'|' -f3,4,7 $arg1 | uniq > filetmp.tc
head -1 filetmp.tc > file.tc;
tail -n+2 filetmp.tc | sort -t"|" -k2,2 >> file.tc;
cat file_name.txt | sed 1d | sort
这将做你想做的。