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
데이터가 아직 정렬되지 않은 경우 datamash
with --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