サンプルファイル:
最初の列には次のものがあります。順序付けされていない4つの値で構成される固定セット world1.com,world2.com,world3.com or world4.com
2番目の列は各行に属するキーであるため、4つのグループのそれぞれには一意のランダムキーがあります。
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
は、ドメインごとのキー数(2番目のフィールド)を使用してドメイン数(最初のフィールド)に対して機能する必要があります。ドメイン名可能それぞれに同じ数のキーがありますが、必須ではありません。
%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
シェルがそれをサポートしている場合は、代わりに使用できます$'\n'
。"$NL"