다음 형식의 항목이 포함된 파일이 있습니다 key: value
.
고양이 데이터.txt
name: 'tom'
tom_age: '31'
status_tom_mar: 'yes'
school: 'anne'
fd_year_anne: '1987'
name: 'hmz'
hmz_age: '21'
status_hmz_mar: 'no'
school: 'svp'
fd_year_svp: '1982'
name: 'toli'
toli_age: '41'
같은...
key: value
중복된 키가 있는 키를 단일 항목으로 찾아서 인쇄하면 됩니다 .
아래 코드를 사용하면 중복 키를 얻을 수 있습니다.
cat data.txt | awk '{ print $1 }' | sort | uniq -d
name:
school:
그러나 나는 중복 키의 값을 행 내의 위치에 연결하는 출력을 원합니다.
예상 출력:
name: ['tom', 'hmz', 'toli']
school: ['anne', 'svp']
tom_age: '31'
status_tom_mar: 'yes'
fd_year_anne: '1987'
hmz_age: '21'
status_hmz_mar: 'no'
fd_year_svp: '1982'
toli_age: '41'
뭔가 제안해주실 수 있나요?
답변1
존재하다 awk
:
$ awk -F': ' '
{
count[$1]++;
data[$1] = $1 in data ? data[$1]", "$2 : $2
}
END {
for (id in count) {
printf "%s: ",id;
print (count[id]>1 ? "[ "data[id]" ]" : data[id])
}
}' data.txt
hmz_age: '21'
tom_age: '31'
fd_year_anne: '1987'
school: [ 'anne', 'svp' ]
name: [ 'tom', 'hmz', 'toli' ]
toli_age: '41'
fd_year_svp: '1982'
status_hmz_mar: 'no'
status_tom_mar: 'yes'
펄 방법:
$ perl -F: -lane 'push @{$k{$F[0]}},$F[1];
END{
for $key (keys(%k)){
$data="";
if(scalar(@{$k{$key}})>1){
$data="[" . join(",",@{$k{$key}}) . "]";
}
else{
$data=${$k{$key}}[0];
}
print "$key: $data"
}
}' data.txt
status_tom_mar: 'yes'
fd_year_anne: '1987'
tom_age: '31'
toli_age: '41'
fd_year_svp: '1982'
hmz_age: '21'
school: [ 'anne', 'svp']
name: [ 'tom', 'hmz', 'toli']
status_hmz_mar: 'no'
아니면 조금 더 이해하기 쉬울 수도 있습니다.
perl -F: -lane '@fields=@F;
push @{$key_hash{$fields[0]}},$fields[1];
END{
for $key (keys(%key_hash)){
$data="";
@key_data=@{$key_hash{$key}};
if(scalar(@key_data)>1){
$data="[" . join(",", @key_data) . "]";
}
else{
$data=$key_data[0]
}
print "$key: $data"
}
}' data.txt
답변2
짧은 awk
프로그램이 당신을 위해 이것을 달성할 것입니다
awk -F': ' '
# Every line of input; fields split at colon+space
{
# Append a comma if we have previous items
if (h[$1] > "") { h[$1] = h[$1] ", " };
# Append the item and increment the count
h[$1] = h[$1] $2;
i[$1]++
}
# Finally
END {
# Iterate across all the keys we have found
for (k in h) {
if (i[k] > 1) { p = "[%s]" } else { p = "%s" };
printf "%s: " p "\n", k, h[k]
}
}
' data.txt
산출
hmz_age: ['21', '41']
tom_age: '31'
fd_year_anne: ['1987', '1982']
school: ['anne', 'svp']
name: ['tom', 'hmz', 'toli']
status_hmz_mar: 'no'
status_tom_mar: 'yes'
답변3
전혀:
awk '{arr[$1][length(arr[$1])+1]=$2}; END {for (i in arr) {printf i;if (length(arr[i])>1) {xc=" [";for (rr in arr[i]) {printf xc;printf arr[i][rr];xc=","} print "]"} else print arr[i][length(arr[i])]} }' data.txt
산출:
hmz_age:'21'
fd_year_svp:'1982'
fd_year_anne:'1987'
name: ['tom','hmz','toli']
school: ['anne','svp']
status_tom_mar:'yes'
tom_age:'31'
toli_age:'41'
status_hmz_mar:'no'
답변4
1 단계
for i in $(awk -F ":" '{a[$1]++}END{for(x in a){print x,a[x]}}' file.txt | awk '$NF>1{print $1}'|tac); do grep "^$i" file.txt >/dev/null; if [[ $? == 0 ]]; then awk -v i="$i" -F ":" '$1 == i{print $2}' file.txt|awk 'END{print "\n"}ORS=","'|sed "s/^,//g"|sed "s/,$//g"|awk -v i="$i" '{print i":["$0"]"}';else grep -v "^$i" file.txt;fi; done >output.txt
2 단계
for i in $(awk -F ":" '{a[$1]++}END{for(x in a){print x,a[x]}}' file.txt| awk '$NF==1'); do awk -v i="$i" -F ":" '$1 ~ i' file.txt; done >>output.txt
산출
name: ['tom', 'hmz', 'toli']
school: ['anne', 'svp']
tom_age: '31'
status_tom_mar: 'yes'
fd_year_anne: '1987'
hmz_age: '21'
status_hmz_mar: 'no'
fd_year_svp: '1982'
toli_age: '41'