탭으로 구분 된 파일 정렬


180

다음 형식의 데이터가 있습니다.

foo<tab>1.00<space>1.33<space>2.00<tab>3

이제 마지막 필드를 기준으로 파일을 점차적으로 정렬하려고했습니다. 다음 명령을 시도했지만 예상대로 정렬되지 않았습니다.

$ sort -k3nr file.txt  # apparently this sort by space as delimiter

$ sort -t"\t" -k3nr file.txt
  sort: multi-character tab `\\t'

$ sort -t "`/bin/echo '\t'`" -k3,3nr file.txt
  sort: multi-character tab `\\t'

올바른 방법은 무엇입니까?

샘플 데이터 는 다음과 같습니다 .

답변:


312

bash 사용 하면 트릭을 수행합니다.

$ sort -t$'\t' -k3 -nr file.txt

작은 따옴표로 묶은 문자열 앞에 달러 기호가 있습니다. bash 매뉴얼 페이지ANSI-C Quoting 섹션 에서 이에 대해 읽을 수 있습니다 .


2
사용 '"'"' 별칭 내에서 사용할 수 있습니다.
Pablo A

이 delimeter를 전달하여 awk 명령 내에서 정렬하는 방법을 보여줄 수 있습니까? awk '{print $0 | "sort -nr" > "outfile" }' datafile이스케이프 된 탭 델리 미터가 sort 명령으로 전송 된 경우를 제외하고
멀린

11

기본적으로 필드 구분 기호는 공백이 아닌 공백으로 전환되므로 탭이 제대로 작동합니다.

그러나 열은 기본 1과 기본 0으로 색인화되므로 원하는 경우

sort -k4nr file.txt

file.txt를 열 4를 기준으로 숫자 순으로 정렬합니다. (문제의 데이터에는 5 개의 필드가 있으므로 마지막 필드는 색인 5입니다.)


4
이것은 탭으로 구분 된 필드 사이의 공백 문자 수가 모든 입력 행에 대해 동일한 경우에만 작동합니다.
Lars Haugseth 2016 년

5

-t \ 뒤에 실제 탭 문자를 넣고 쉘에서 ctrl-v를 누른 다음 탭 문자를 입력해야합니다. 필자가 사용한 대부분의 쉘은이 리터럴 탭 항목 모드를 지원합니다.

그러나 다른 장소에서 복사하여 붙여 넣기하는 경우 일반적으로 탭이 유지되지 않으므로주의하십시오.


이것이 가장 좋은 답변입니다. emacs를 사용하면 C-q <tab>예를 들어 '인서트 삽입'모드에서이를 수행 할 수 있습니다 . 나는 그것이 ^V나노 라고 생각합니다 .
Wyatt8740

3

$ 솔루션이 효과가 없었습니다. 그러나 실제로 명령에 탭 문자를 넣으면 sort -t ''-k2


1
사용 <C-v><Tab>순서는 탭 키 쉘에서 자동 완성 기능에 사용되는 경우에 탭을 삽입합니다.
Júda Ronén

1
ANSI 인용 $'\t'은 ksh, zsh 및 bash에서 작동합니다. Bourne 쉘은이를 지원하지 않습니다. 이 게시물 참조 : unix.stackexchange.com/a/371873/201820
codeforester

1

같은 것을 통해 파이프 awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. 공백이 탭으로 변경됩니다.


@MB : 공간을 그대로 유지해야합니다.
neversaint

1
확실한 방법은 없지만, awk를 통해 데이터를 파이핑하거나, 공백을 탭으로 변경하고, 데이터를 정렬 한 다음, awk를 통해 다시 파이핑하여 탭을 다시 공백으로 변경하는 것을 막을 수있는 방법은 없습니다.
Michiel Buddingh

1
보존하려는 탭과 공백이 혼합되어 있으면 작동하지 않습니다.
제임스 톰슨

1

사람들이 항상 탭과 공백을 혼동하기 때문에이를 피할 수 있다면 일반적으로 이와 같은 데이터를 유지하는 것은 좋은 방법이 아닙니다.

Perl, Python 또는 Ruby와 같은 스크립팅 언어에서 문제를 해결하는 것은 매우 간단합니다. 예제 코드는 다음과 같습니다.

#!/usr/bin/perl -w

use strict;

my $sort_field = 2;
my $split_regex = qr{\s+};

my @data;
push @data, "7 8\t 9";
push @data, "4 5\t 6";
push @data, "1 2\t 3";

my @sorted_data = 
    map  { $_->[1] }
    sort { $a->[0] <=> $b->[0] }
    map  { [ ( split $split_regex, $_ )[$sort_field], $_ ] }
    @data;

print "unsorted\n";
print join "\n", @data, "\n";
print "sorted by $sort_field, lines split by $split_regex\n";
print join "\n", @sorted_data, "\n";

1

Windows에서 Gnu 정렬 솔루션을 원했지만 위의 솔루션 중 어느 것도 명령 줄에서 효과가 없었습니다.

Lloyd의 단서를 사용하여 다음 배치 파일 (.bat)이 효과적이었습니다.

큰 따옴표 안에 탭 문자를 입력하십시오.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1
그래 여기에 트릭 그렇지 않으면 작동하지 않습니다하는 .BAT 파일에 넣어입니다
카를로스 렌던

1

'general-numeric-sort'를 사용할 때 bash 쉘에서 cygwin의 정렬과 관련 하여이 문제가 발생했습니다. 내가 지정한 경우 -t$'\t' -kFgF는 필드 번호입니다, 그것은 작동하지 않았다,하지만 난 둘 다 지정된 경우 -t$'\t'-kF,Fg(예를 들어 -k7,7g7 필드)는 일을했다. -kF,Fg없이는 -t$'\t'작동하지 않았다.


0

탭만 사용하여 더 쉽게 만들려면 공백을 탭으로 바꾸십시오.

tr " " "\t" < <file> | sort <options>

내 tr은 파일을 읽지 않고 XD 만 스트리밍합니다. usage: tr [-Ccsu] string1 string2
The Unfun Cat

1
tr string1 string2 <some-file. stdin을 읽을 수있는 한 모든 파일을 읽을 수 있습니다.
Randal Schwartz

0

Lars Haugseth의 대답은 명령 줄에서 나만 쉘 스크립트에서 실행될 경우이 오류가 발생하는 경우에만 작동했습니다.

정렬 : 다중 문자 탭 '$ \ t'

누군가 가보고있는 경우 쉘 스크립트로 코딩 된 솔루션

sort -t'    '

탭 문자는 따옴표 사이에 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.