내가 시도한 것

내가 시도한 것

user-history.txt다음 패턴의 파일이 있습니다 .

user-1 6
user-1 7
user-2 6
user-2 7
user-2 8
user-3 6
user-3 7
user-3 9
user-4 6

각 사용자가 한 번만 언급되도록 레코드를 병합하고 두 번째 열을 별도로 병합하고 싶습니다.

원하는 출력

user-1 6,7
user-2 6,7,8
user-3 6,7,9
user-4 6

내가 시도한 것

아직 경험이 부족해서 이 문제를 해결할 수 없습니다. 다른 솔루션을 찾고 있는데 비슷한 질문이 있지만 특정 문제를 해결하는 방법을 찾지 못했습니다.

(G)AWK가 이 작업을 위한 가장 쉬운 도구가 아니라면 다른 솔루션을 사용할 수 있습니다.

자세한 설명을 해주시면 지식이 향상될 것입니다.

답변1

$ datamash -W groupby 1 collapse 2 <user-history.txt
user-1  6,7
user-2  6,7,8
user-3  6,7,9
user-4  6

이는 GNU를 사용하여 datamash두 번째 열( )의 항목을 축소하고 이를 collapse 2첫 번째 열( , 또는 )의 키로 그룹화하여 연속 공백 문자를 필드 구분 기호( , 또는 )로 처리합니다.groupby 1-g 1-W--whitespace

데이터가 아직 정렬되지 않은 경우 datamashwith --sort또는 를 사용하고 -s, 무시하려는 데이터에 중복된 키-값 쌍이 있는 경우 unique 2대신 을 사용하세요 collapse 2.

답변2

$ cat tst.awk
$1 != prev {
    if ( prev != "" ) {
        print prev, vals
    }
    prev = $1
    vals = $2
    next
}
{ vals = vals "," $2 }
END {
    print prev, vals
}

$ awk -f tst.awk file
user-1 6,7
user-2 6,7,8
user-3 6,7,9
user-4 6

무슨 역할을 하는지는 너무나 당연하고 설명이 필요 없을 것 같지만, 이해가 안 되는 부분이 있다면 아래 댓글로 질문해주세요.

답변3

한 가지 방법은 다음과 같습니다.

{
  if ($1 in users) users[$1] = users[$1] "," $2
  else users[$1] = $2
}

END { for (user in users) { print user, users[user] } }

이는 각 행을 살펴보고 사용자가 표시되었는지 확인합니다(배열에 의해 결정됨 users). 그렇다면 저장된 정보에 두 번째 레코드를 쉼표로 구분하여 추가하고, 그렇지 않으면 두 번째 레코드를 사용하여 저장된 정보를 초기화합니다.

모든 입력이 처리되면 users배열이 반복되고 저장된 정보가 추출되어 인쇄됩니다.

사용자의 순서는 유지되지 않습니다. GAWK를 사용하고 있으므로 다음을 사용할 수 있습니다.확장이 문제를 해결하세요:

END { PROCINFO["sorted_in"] = "@ind_str_asc"; for (user in users) { print user, users[user] } }

답변4

한 가지 접근 방식은 다음과 같습니다.

awk '
NR==1||prev!=$1{
  if (NR!=1) { print RS}
  print;prev=$1
  next
}
{ $1=",";print }
END{print RS}
' OFS= ORS= file

user-1 6,7
user-2 6,7,8
user-3 6,7,9
user-4 6

관련 정보