我有一个固定宽度字段的文件,我试图使用UNIX(在我的情况下是Cygwin)排序实用程序进行排序。
问题是文件顶部有一个双行标题,它被排序到文件的底部(因为每个标题行都以冒号开头)。
有没有办法告诉排序“将前两行传递给未排序的”或指定排序将冒号行排序到顶部 - 其余行总是以6位数字开头(实际上是我正在整理的关键)如果有帮助的话。
示例:
: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
答案 0 :(得分:97)
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile
括号创建一个子shell,包装stdout,这样你就可以管它或重定向它,就像它来自一个命令一样。
答案 1 :(得分:47)
如果您不介意使用awk
,则可以利用awk
的内置管道功能
例如
extract_data | awk 'NR<3{print $0;next}{print $0| "sort -r"}'
这将逐字打印前两行,并通过sort
管理其余部分。
请注意,这具有能够有选择地对零件进行分类的特定优势 管道输入。建议的所有其他方法只会对可以多次读取的普通文件进行排序。这适用于任何事情。
答案 2 :(得分:27)
这是一个适用于管道数据的版本:
(read -r; printf "%s\n" "$REPLY"; sort)
如果标题有多行:
(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)
此解决方案来自here
答案 3 :(得分:6)
您可以使用tail -n +3 <file> | sort ...
(tail会输出第3行的文件内容)。
答案 4 :(得分:4)
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
答案 5 :(得分:3)
只需2行代码......
head -1 test.txt > a.tmp;
tail -n+2 test.txt | sort -n >> a.tmp;
对于数字数据,需要-n。对于alpha排序,不需要-n。
示例文件:
$ cat test.txt
头
8
5
100个
1
-1
结果:
$ cat a.tmp
头
-1
1
5
8
100
答案 6 :(得分:1)
所以这里是一个bash函数,其中参数与sort完全相同。支持文件和管道。
var urlString: String = "www.apple.com"
if !urlString.starts(with: "http://") && !urlString.starts(with: "https://") {
urlString = "http://\(urlString)"
}
if let url: URL = URL(string: urlString) {
let urlRequest: URLRequest = URLRequest(url: url)
webView.load(urlRequest)
urlTextField.text = urlString
}
工作原理。该行检查是否至少有一个参数,以及最后一个参数是否为文件。
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}
最后,我们执行awk部分,传递参数(减去最后一个参数,如果它是文件)以在awk中排序。这是Dave的中心建议,并修改为采用排序参数。如果我们进行管道处理, set -- "${@:1:$(($#-1))}"
将为空,我们依赖这一事实,因此被忽略。
$file
使用逗号分隔文件的示例。
awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
答案 7 :(得分: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)
答案 8 :(得分:0)
这是从其他答案派生的bash shell函数。它处理文件和管道。第一个参数是文件名或stdin的' - '。剩余的参数传递给sort。几个例子:
$ 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
}
答案 9 :(得分:0)
这与Ian 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;
答案 10 :(得分:0)
在简单情况下,sed
可以轻松完成工作:
your_script | (sed -u 1q; sort)
或等效地
cat your_data | (sed -u 1q; sort)
键位于1q
中-打印第一行(标题)并退出(将其余输入留给sort
)。
对于给定的示例,2q
可以解决问题。
对于这些-u
(特别是GNU)来说,sed
开关(无缓冲)是必需的,否则它们会分块读取输入,从而消耗要通过{{1}的数据}。
答案 11 :(得分:-4)
cat file_name.txt | sed 1d | sort
这将做你想要的。