awk의 행 내에서 왼쪽에서 오른쪽으로 정렬하는 방법은 무엇입니까?

awk의 행 내에서 왼쪽에서 오른쪽으로 정렬하는 방법은 무엇입니까?

XML 유형 태그가 포함된 대용량 데이터 파일이 있습니다. 각 행은 고유한 항목을 참조하며 다양한 수의 속성 필드를 포함합니다. 해당 행의 번호가 매겨진 레이블을 기준으로 행을 가장 낮은 것부터 가장 높은 것까지 정렬하고 중복 항목을 제거해야 합니다. awk를 사용하여 각 줄에서 이 작업을 수행할 수 있습니까?

<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 7>KNOB</7>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>,< 2>TYLO</2>,< 2>PASS</2>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>

답변1

나는 이것을 위해 Perl을 사용할 것입니다:

perl -MList::Util=uniq -F, -lane '
    $item = shift @F;
    @fields = uniq sort @F;
    print join ",", $item, @fields;
' file

산출:

<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 2>TYLO</2>,< 5a>RIGHT</5a>,< 7>KNOB</7>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>

라인을 이해하기 더 어렵게 작성할 수도 있습니다.

perl -MList::Util=uniq -F, -lape '$"=","; $_="@{[$F[0], uniq sort @F[1..$#F]]}"' file

태그 내용에 쉼표가 포함되지 않기를 바랍니다.

답변2

awk만 사용하는 이유가 있나요? 문제를 해결하려면 먼저 데이터를 각 단위로 분할하고 정렬하고 중복 항목을 제거한 다음 다시 결합해야 합니다. 가장 유능한 프로그래밍 언어나 스크립팅 언어(C도 포함)를 사용하여 이 작업을 수행할 수 있지만, 필요한 작업을 수행하는 도구가 이미 있는 경우 다시 개발할 가치가 있습니까?

게시하는 데이터가 작업 중인 데이터를 실제로 표현한 경우 다음을 사용하여 신속하게 처리할 수 있습니다.

$ cat RAW_DATA
<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 7>KNOB</7>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>,< 2>TYLO</2>,< 2>PASS</2>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>
$ while read line; do echo "$(cut -d, -f1 <<< "$line"),$(cut -d, -f2- <<< "$line" | tr ',' '\n' | sort -n | uniq | paste -sd,)"; done < RAW_DATA
<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 2>TYLO</2>,< 5a>RIGHT</5a>,< 7>KNOB</7>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>

while루프는 파일의 각 줄을 읽고 개별적으로 처리합니다. 그런 다음 cut -d, -f1 <<< "$line"첫 번째 필드만 추출되는(정적이므로) 새 행을 에코하고 cut -d, -f2- <<< "$line" | tr ',' '\n' | sort -n | uniq | paste -sd,나머지 필드를 추출하고 숫자로 정렬하고 고유한 값을 필터링하고 paste -sd,쉼표로 구분된 목록을 다시 결합하는 데 사용하려고 합니다.

관련 정보