두 번째 열의 키를 사용하여 파일의 4개 행마다 첫 번째 열을 정렬하는 방법

두 번째 열의 키를 사용하여 파일의 4개 행마다 첫 번째 열을 정렬하는 방법

예시 파일:

첫 번째 열은 다음을 가질 수 있습니다.순서가 지정되지 않은 4개의 값으로 구성된 고정 세트 world1.com,world2.com,world3.com or world4.com

두 번째 열은 각 행에 속하는 키이므로 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는 도메인당 키 개수(두 번째 필드)를 사용하여 도메인 개수(첫 번째 필드)에 대해 작동해야 합니다. 도메인 이름가능한각각에는 동일한 수의 키가 있지만 필수는 아닙니다.

%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"

관련 정보