교활한. date
배열을 사용 하고 bash를 사용하는 것이 가능하지만 실제로는 실제 프로그래밍 언어의 이점이 있습니다. 예를 들어 Perl에서 :
$ perl -ne '$d=$1 if /(.+?),/; $k{$d}.=$_; END{print $k{$_} for sort keys(%k);}' log*
01:02:03.6497,2224,0022 foo
foo1
2foo
foo3
01:03:03.6497,2224,0022 FOO
FOO1
2FOO
FOO3
01:04:03.6497,2224,0022 bar
1bar
bar2
3bar
다음은 주석 처리 된 스크립트로 압축되지 않은 것과 같습니다.
#!/usr/bin/env perl
## Read each input line, saving it
## as $_. This while loop is equivalent
## to perl -ne
while (<>) {
## If this line has a comma
if (/(.+?),/) {
## Save everything up to the 1st
## comma as $date
$date=$1;
}
## Add the current line to the %k hash.
## The hash's keys are the dates and the
## contents are the lines.
$k{$date}.=$_;
}
## Get the sorted list of hash keys
@dates=sort(keys(%k));
## Now that we have them sorted,
## print each set of lines.
foreach $date (@dates) {
print "$k{$date}";
}
이 모든 일의 라인과 고 가정합니다 에만 날짜 라인에 쉼표가 포함되어 있습니다. 그렇지 않은 경우 대신 다음을 사용할 수 있습니다.
perl -ne '$d=$1 if /^(\d+:\d+:\d+\.\d+),/; $k{$d}.=$_; END{print $k{$_} for sort keys(%k);}' log*
위의 방법은 파일의 전체 내용을 메모리에 보관해야합니다. 그것이 문제라면, 여기에없는 것이 있습니다 :
$ perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log* |
sort -n | perl -lne 's/\0/\n/g; printf'
01:02:03.6497,2224,0022 foo
foo1
2foo
foo3
01:03:03.6497,2224,0022 FOO
FOO1
2FOO
FOO3
01:04:03.6497,2224,0022 bar
1bar
bar2
3bar
이것은 줄 바꿈을 바꾸어 연속 타임 스탬프 사이의 모든 줄을 한 줄로 \0
만듭니다. 이는 전달 sort
하고 tr
다시 라인을 얻을 수 있습니다.
OP에서 매우 정확하게 지적했듯이 위의 모든 솔루션을 수정해야하며 파일을 병합 할 수 있다는 점을 고려하지 마십시오. 다음은 다른 파일과 달리 두 파일에서만 작동하는 파일입니다.
$ sort -m <(perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log1) \
<(perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log2) |
perl -lne 's/[\0\r]/\n/g; printf'
그리고 perl 명령을 별명으로 저장하면 다음을 얻을 수 있습니다.
$ alias a="perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/'"
$ sort -m <(a log1) <(a log2) | perl -lne 's/[\0\r]/\n/g; printf'