2016-12-17 4 views
0

같은 입력 목록을 감안할 때 다음과 같은 : 당신이 볼 수 있듯이 (첫 번째 필드가 무작위로 다른 GNU "종류"와 원래의 정렬 순서를 유지하면서 어떻게 무작위 분류 한 키에

405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
004:[email protected] 
004:[email protected] 
004:[email protected] 
101:[email protected] 
101:br[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
005:[email protected] 
005:[email protected] 
005:[email protected] 

했다

(원래 입력에는 숫자 순서대로 첫 번째 필드가 모두 있고 004는 첫 번째 문자 다음에 005, 101, 405 등) 두 번째 필드는 첫 번째 문자의 알파벳 순서로 배열되어 있습니다.)

원한다면 첫 번째 필드 (콜론 ':'로 구분됨)가 무작위로 정렬되어 임의의 정렬 동안 두 번째 필드의 모든 항목이 중요하지 않은 무작위 정렬이 필요합니다. 첫 번째 필드가 동일한 모든 라인은 그룹화되어 있지만 파일 전체에 무작위로 분포되어 있으므로 두 번째 필드도 임의로 정렬됩니다. 즉, 최종 출력에서 ​​첫 번째 필드에서 동일한 값을 가진 행이 함께 그룹화되지만 (파일 전체에 임의로 분산 됨) 두 번째 필드가 임의로 정렬됩니다. 나는 정렬 키와 이것 저것에 너무 익숙하지 않기 때문에이 원하는 결과를 얻을 수 없다.

405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
004:[email protected] 
004:[email protected] 
004:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
005:[email protected] 
005:[email protected] 
005:[email protected] 

사람이 종류의이 유형을 달성하는 방법을 알고 있나요

: 원하는 출력은 다음과 비슷하게

?

감사합니다.

답변

2

awk으로 쉽게 처리 할 수 ​​있습니다. 쉽게 설명 떨어져 깨진

awk -F: 'BEGIN{cmd="sort -R"} $1 != key {close(cmd)} {key=$1; print | cmd}' input.txt 

또는 :

한 라이너로

  • -F: - 대장로 설정 AWK의 필드 분리.
  • BEGIN{cmd="sort -R"} - 시작하기 전에 "임의 정렬"을 수행 할 명령 인 변수를 설정하십시오. 이것은 FreeBSD에서 저에게 적합합니다. GNU 정렬 작업을해야합니다.
  • $1 != key {close(cmd)} - 전류 선이 마지막으로 처리 된 것과 다른 제 필드가 있으면, ...
  • {key=$1; print | cmd}를 출력 파이프습니다 - 그리고 마지막으로, "키"VAR을 설정하고, 현재 라인의 배관 출력을 인쇄 변수 cmd에 저장된 명령을 통해

이 사용법은 약간의 awk awesomeness를 이용합니다. 문자열을 파이프하면 (변수에 저장되거나 저장되지 않음), 파이프는 사용시 자동으로 만들어집니다. 언제든지 닫을 수 있으며 이후에 사용하면 새 명령이 다시 열립니다.

이 영향은 close(cmd) 때마다 현재 임의로 정렬 된 줄 집합을 인쇄한다는 것입니다. awk는 파일 끝에 도달하면 자동으로 cmd을 닫습니다.

물론이 솔루션이 작동하려면 공유 된 첫 번째 필드가있는 모든 줄이 함께 그룹화되어 있어야합니다.

+0

을지지 않습니다이 대안. 'awk'한 줄 짜기로 끝내는 것도 놀라운 일입니다. 나는 PHP에서 같은 것을 구현했지만 배열 트래버 설 (array traversal)과 셔플 링 (shuffling)을 많이 포함하는 약 30 행의 코드 (파일 읽기, 구문 검사 등)에서 구현했습니다. 확실히 훨씬 빠르고 효율적입니다. – Brendan

+0

제 원래의 질문에 따르면, GNU 'sort'가 가능한지 알고 있습니까? 나는 그렇게 생각하지 않는다. 그렇다면 정렬 구문을보고 싶다. – Brendan

+0

나는 GNU sort를 단독으로 사용하는 것이 불가능하다고 확신한다. 질문에 설명 된 정렬은 첫 번째 필드별로 그룹화 된 단순한 무작위 화처럼 단순합니다. 정렬이 아닙니다. 결론은 GNU sort 만 사용하여 무작위 화합니다. 이 명령을 다른 명령으로 대체 할 수 있습니다. 각 섹션의 순서를 역순으로 바꾸는'tac '또는 전자 메일의 본문으로 각 그룹을 보내는'mailx'가 있습니다. – ghoti

1

우아하지하지만 다른 방법

$ awk -F: '!($1 in a){a[$1]=c++} {print a[$1] "\t" $0}' file | 
    sort -R -k2 | 
    sort -nk1,1 -s | 
    cut -f2- 

또는 초기 그룹을 확실히했다

$ sort -R file | 
    awk -F: '!($1 in a){a[$1]=c++} {print a[$1] "\t" $0}' | 
    sort -nk1,1 -s | 
    cut -f2-