리눅스 awk 질문

xjstk1234의 이미지

안녕하세요.awk를 이용하여 중복된 라인을 출력하고 싶습니다.

텍스트에 아래와 같은 내용이 있다고 치면..
111:aa:xtp1:ada
111:aet:xtp1:papa
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp3:bdk
222:cc:xtp4:eq
222:ap:xtp2:lstp

3번째 필드(xtp부분) 기준으로 중복된 라인을 출력하고 싶습니다. (중복 검사 시 사용된 기준과 대상 모두.)

원하는 결과 :
111:aa:xtp1:ada
111:aet:xtp1:papa
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp4:eq
222:ap:xtp2:lstp

아래와 같은 명령어는 중복된 대상?만 출력을 해주더라구요.

입력 :
cat test.txt | awk -F: 'tmp[$3]++'

결과 :
111:aet:xtp1:papa
111:ab:xtp2:adad
111:ac:xtp4:lk

중복된 라인 모두 출력하고 싶은데 어떤 방법이 있을까요..?

cat test.txt | awk -F: '{print $3}' | sort | uniq -D

이와 같이 쓰면 전체 라인 출력이 안 되구.. 이 역시 대상?만 출력이 되어 고민이네요..

chanik의 이미지

글의 설명과 예시된 결과가 서로 맞지 않는 것 같아 헷갈리지만,
아래와 같이 하시면 $3 기준으로 중복된 라인은 생략하고 최초 등장한 라인만 출력됩니다.

$ cat test.txt | awk -F: '{if(!tmp[$3]++) print}'
111:aa:xtp1:ada
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp3:bdk

그냥 아래와 같이 해도 결과가 같네요

$ cat test.txt | awk -F: '!tmp[$3]++'
111:aa:xtp1:ada
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp3:bdk

xjstk1234의 이미지

먼저 답변 감사드립니다.

$ cat test.txt | awk -F: '!tmp[$3]++'
위 명령어에서 중복 값을 보기 위해 부정(!)을 빼보았는데 중복으로 간주된 라인만 출력이 되더라구요.

제가 원하는 결과는 1번 라인과 3번 라인이 중복일 경우,
1번과 3번 모두 출력되길 원합니다.

쉽게 말해서..
예시에서 $3 기준으로 xtp3 빼고 전부 중복되는 라인이라
xtp3 빼고 모두 출력시키고 싶습니다.

chanik의 이미지

출력 순서가 중요하지 않다면 아래와 같이 하면 중복이 발생한 줄만 출력되네요. 중복이 발생한 걸 처음 확인한 시점, 즉 두 번째 등장한 시점에 기준과 대상이 처음 출력되므로 출력순서 섞임이 발생합니다. 순서도 지켜져야 한다면, 중복판단과 출력의 두 단계를 분리하여 two pass 식으로 해야 할 것 같네요.

$ cat test.txt | awk -F: '
{ switch(tmp[$3]++) {
    case 0:  buf[$3] = $0; break;
    case 1:  print buf[$3]; delete buf[$3];
    default: print $0; break;
  }
}'
111:aa:xtp1:ada
111:aet:xtp1:papa
111:ac:xtp4:lk
222:cc:xtp4:eq
111:ab:xtp2:adad
222:ap:xtp2:lstp
xjstk1234의 이미지

지금 단계에서 순서는 딱히 상관이 없어서 이대로 써도 되겠네요!! ㅎㅎ
나중에 필요하다면 말씀해주신대로 해보겠습니다.

답변 감사합니다!

chanik의 이미지

아래와 같이 two pass로 하면 순서도 지킬 수 있겠습니다.

$ awk -F: '
BEGINFILE{
  while(( getline line < FILENAME ) > 0 ) {
    split(line,word,":");
    tmp[word[3]]++;
  }
}
{ if(tmp[$3] > 1) print }' test.txt
111:aa:xtp1:ada
111:aet:xtp1:papa
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp4:eq
222:ap:xtp2:lstp

단, 입력 데이터가 파일로 존재해야 two pass가 성립되므로, cat test.txt | awk ... 식의 실행은 안 되고, awk ... test.txt 식의 실행만 가능합니다. 그리고 명령행에 awk 스크립트를 넣다보니 모양이 사나운데, 아래와 같이 awk 스크립트로 만들면 보기 편해집니다.

$ cat sample.awk
#!/usr/bin/awk -f
 
BEGINFILE{
  FS=":"
  while(( getline line < FILENAME ) > 0 ) {
    split(line,word,FS);
    tmp[word[3]]++;
  }
}
{
  if(tmp[$3] > 1) print;
}
 
$ awk -f sample.awk test.txt 또는 ./sample.awk test.txt 식으로 실행
111:aa:xtp1:ada
111:aet:xtp1:papa
111:ab:xtp2:adad
111:ac:xtp4:lk
222:cc:xtp4:eq
222:ap:xtp2:lstp
swish95의 이미지

awk 구조상 그런식으로는 안될듯 한데요?

물론 여러단계로 감싸면 되겠지만 python 이나 shell 로 짜는게 빠를듯 합니다.

------------------------------------------------------------
ProgrammingHolic

xjstk1234의 이미지

저도 그렇게 생각하구 도저히 안 될 것 같아서 질문 올린건데
위에 답변해주신대로 하니 너무 길지도 않고 잘 되네요.

사정상 python 사용을 못하고 쉘도 애매해서..ㅠ

그래도 답변 감사합니다.

swish95의 이미지

되면 된거죠 ^^

어차피 저것도 짧은 shell 프로그램이니까요 ^^

------------------------------------------------------------
ProgrammingHolic

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.