示例文件:
第一列可以有固定的 4 个无序值集 world1.com,world2.com,world3.com or world4.com
第二列是属于每一行的密钥,使得四组中的每一组都有唯一的随机密钥。
world4.com /randomkeyhghgdh778/key67567
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world1.com /randomkeyhueh34778/key67uuu77
world4.com /randomkey8998382/key6hh77686
world3.com /randomkey7HHHH0000/key6333355k
world2.com /randomkeyJJJJ1111/key63333
等等
期望的输出:
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world4.com /randomkeyhghgdh778/key67567
world1.com /randomkeyhueh34778/key67uuu77
world2.com /randomkeyJJJJ1111/key63333
world3.com /randomkey7HHHH0000/key6333355k
world4.com /randomkey8998382/key6hh77686
答案1
按世界组织文件:
$ paste -d'\n' <(grep world1 file) <(grep world2 file) <(grep world3 file) <(grep world4 file)
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world4.com /randomkeyhghgdh778/key67567
world1.com /randomkeyhueh34778/key67uuu77
world2.com /randomkeyJJJJ1111/key63333
world3.com /randomkey7HHHH0000/key6333355k
world4.com /randomkey8998382/key6hh77686
怎么运行的
我们可以用它grep
来选择每个世界的线:
$ grep world4 file
world4.com /randomkeyhghgdh778/key67567
world4.com /randomkey8998382/key6hh77686
paste
合并多个文件中的行。粘贴命令可能如下所示:
paste -d'\n' file1 file2 file3 file3.
我们实际上不必为每个世界创建真实的文件。相反,我们可以使用以下方法为每个对象创建类似文件的对象流程替代:
paste -d'\n' <(grep world1 file) <(grep world2 file) <(grep world3 file) <(grep world4 file)
工艺替代bash、zsh 以及 AT&T ksh88 和 ksh93 支持,但不支持 dash、pdksh 或 mksh。
额外功能:按键排序
为了说明这种方法的灵活性,我们将对每个世界的键进行排序。 注意:排序会分解多组行。如果您想将集合放在一起,请不要使用此功能。
我们可以使用 来分隔世界grep
,然后使用sort
每个世界,然后使用 来将这些行重新合并在一起paste
:
$ paste -d'\n' <(grep world1 file | sort -k2,2) <(grep world2 file | sort -k2,2) <(grep world3 file | sort -k2,2) <(grep world4 file | sort -k2,2)
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world4.com /randomkey8998382/key6hh77686
world1.com /randomkeyhueh34778/key67uuu77
world2.com /randomkeyJJJJ1111/key63333
world3.com /randomkey7HHHH0000/key6333355k
world4.com /randomkeyhghgdh778/key67567
请注意,这sort
取决于区域设置。不同locales
可能会导致不同的顺序。
答案2
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use open qw< :encoding(ASCII) >;
my $filename = $ARGV[0];
my ($ip_fh, $op_fh);
open($ip_fh, "<", $filename);
open($op_fh, ">", "$filename".".sorted");
my @ip_lines = <$ip_fh>;
for(my $i = 0; $i <= $#ip_lines; $i++)
{
print $op_fh sort @ip_lines[$i..($i+3)];
$i += 3;
}
close($ip_fh);
close($op_fh);
给出输入文件名作为命令行参数,例如:
./sort_blocks.pl data.txt
答案3
该perl
脚本应适用于任意数量的域(第一个字段),每个域具有任意数量的键(第二个字段)。域名可能每个都有相同数量的密钥,但不是必须的。
它构建一个散列 ( %domains
),散列的每个元素都包含一个键数组。在此过程中,它会跟踪任何域中看到的最大数量的密钥。
读取所有输入后,它会打印每个域存在的每个密钥。
#! /usr/bin/perl
use strict;
use warnings;
my %domains = ();
my $numkeys = 0;
while(<>) {
chomp;
my ($domain, $key) = split;
push @{ $domains{$domain} }, $key;
# find the largest number of keys for any domain
$numkeys = scalar @{ $domains{$domain} } if (scalar @{ $domains{$domain} } gt $numkeys);
}
for my $keynum (0..$numkeys-1){
foreach my $domain (sort keys %domains) {
print "$domain\t$domains{$domain}[$keynum]\n" if (defined($domains{$domain}[$keynum]));
}
}
输出:
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world4.com /randomkeyhghgdh778/key67567
world1.com /randomkeyhueh34778/key67uuu77
world2.com /randomkeyJJJJ1111/key63333
world3.com /randomkey7HHHH0000/key6333355k
world4.com /randomkey8998382/key6hh77686
如果没有相同数量的键被视为错误,请将print "$domain\.....
最后一个代码块中的行替换为:
if (defined($domains{$domain}[$keynum])) {
print "$domain\t$domains{$domain}[$keynum]\n"
} else {
warn "$domain is missing a key\n";
};
如果您希望这是一个致命错误,请替换warn
为。die
答案4
在 GNU 系统上:
$ NL='
'
$ <file xargs -n4 -d "$NL" sh -c 'printf "%s\n" "$@" | sort' sh
world1.com /randomkeygahjuh572/key639839
world2.com /randomkey788gauh72/key63whjk
world3.com /randomkey788gauh72/key63whjk
world4.com /randomkeyhghgdh778/key67567
world1.com /randomkeyhueh34778/key67uuu77
world2.com /randomkeyJJJJ1111/key63333
world3.com /randomkey7HHHH0000/key6333355k
world4.com /randomkey8998382/key6hh77686
如果您的 shell 支持,您可以使用$'\n'
代替。"$NL"