0

我有一个文件,它有很多行,每行都包含一个逗号分隔的列表。我想对这些行中的每一行进行排序。

如果我只有一行,那将很容易:

<file tr ',' '\n' | sort | tr '\n' ','

但是,如果我在我的文件中执行此操作,它会将所有我不想要的行混为一谈。我该如何限制这个?

4

3 回答 3

3

在 Perl 中(相当)容易:

#!/usr/bin/env perl
use strict;
use warnings;

$, = ",";

while (<>)
{
    chomp;
    my @fields = split /,/;
    my @sorted = sort(@fields);
    $sorted[scalar(@sorted)-1] .= "\n";
    print @sorted;
}

技巧在于保存已排序的数组,以便可以将换行符添加到数组的最后一个元素,这样您就不会得到以逗号结尾的行。如果这无关紧要,那么它会更紧凑——将循环的最后三行替换为:

    print sort(@fields), "\n";

输入

x,b,z,a,c,e,f,g,d
3,19,12,17,16,19,18,17,20,16

输出

a,b,c,d,e,f,g,x,z
12,16,16,17,17,18,19,19,20,3

紧凑的代码

它是 Perl,有一些方法可以压缩它:

perl -l -p -a -F, -e '$_ = join(",", sort(@F))' 

那是:

  • -lautochomp 和处理换行符。
  • -p自动读取每个输入行,用脚本处理它,并在每行之后打印。
  • -aF根据字段分隔符将输入行拆分为数组。
  • -F,字段分隔符是逗号。
  • -e紧随其后的是程序。
  • 该程序将默认变量 , 设置为$_数组中排序值的逗号连接列表F

Perl 处理其余部分。

于 2014-03-26T07:29:46.317 回答
1

您可以避免过多的管道并在 GNU awk 中进行所有排序:

awk '{split($0, a, ","); n=asort(a);
      for (i=1; i<=n; i++) printf "%s%s", a[i], (i<n)?OFS:RS}' OFS=, file
于 2014-03-26T07:02:49.167 回答
1

您需要逐行进行。使用循环:

while read -r line; do
  echo "${line}" | tr ',' '\n' | sort | tr '\n' ','
done < file

(说<file tr ',' '\n'会在整个文件中用换行符替换逗号。)

于 2014-03-26T06:17:56.063 回答