有没有办法忽略UNIX排序中的标题行?

时间:2013-01-28 12:49:34

标签: unix sorting command-line

我有一个固定宽度字段的文件,我试图使用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

12 个答案:

答案 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 

这将做你想要的。