두 개의 tab-delimited 파일 비교 질문입니다.

사과먹는 곰돌이의 이미지

안녕하세요. 프로그래밍 초보입니다. tab-delimited 파일 두 개를 비교해서 새로운 tab-delimited 파일을 생성하고자 합니다. awk FNR==NR을 이용해서 처리해 보려고 했는데 생각했던 것과 다른 결과물이 나오네요. 더 나은 방법이 있을까 싶어 질문 올립니다.

input 파일들은 다음과 같습니다.

cat a.txt

1 Hello, world
3 Name: Charlie
2 I have a dog.

cat b.txt

Hello, world
I have a dog.
11 apples
Name: Charlie

b.txt에 있는 문자열 중에 a.txt의 2열에 존재하는 문자열에 대해서는 문자열의 내용과 a.txt의 1열 숫자를 출력하고, b.txt에 있는 문자열 중에 a.txt에 없는 문자열에 대해서는 a.txt의 1열 숫자 대신 0을 출력하려고 합니다.

따라서, 희망하는 output 파일의 형태는 다음과 같습니다.

cat c.txt

Hello, world 1
I have a dog. 2
11 apples 0
Name: Charlie 3

결과적으로 c.txt의 1열은 b.txt의 모든 줄을 포함하도록 하고 싶습니다. 2열은 1열 항목에 대한 a.txt 파일의 숫자값이나 (a.txt 파일에 항목이 없을 경우) 0을 출력하도록 하고요. 아래와 같이 awk로 우선 일치하는 문자열부터 찾아 출력해보고 여기에 수정을 가하려고 했는데, 결과물이 생각과는 다르게 나옵니다.

awk -F '\t' 'FNR==NR{a[$1]=""$2;next};{print a[$1]'\t'$1}' a.txt b.txt > c.txt

위 awk문을 통해 나온 결과물은

cat c.txt

Hello, world
I have a dog.
11 apples
Name: Charlie

결과적으로 2열 숫자값이 출력되지 않았습니다. 비슷한 awk문을 좀더 단순한 문자열을 포함하는 파일에 썼을 때에는 잘 돌아갔었는데...문자열이 복잡하기 때문일까요? 문자열 처리를 위해 ""를 넣어 봤지만 큰 역할을 안 하는 것처럼 보이기도 하고...어렵네요. 혹시 더 나은 처리 방법이 있다면 어떤 게 있을까요.

감사합니다.

ymir의 이미지

$ cat a
1       Hello, world
3       Name: Charlie
2       I have a dog.
 
$ cat b
Hello, world
I have a dog.
11 apples
Name: Charlie
 
$ while read -r line; do V=$(grep -P "^[0-9]+\t$line$" a); set -a ${V:-0 $line}; num=$1; shift; echo $* $num; done < b
Hello, world 1
I have a dog. 2
11 apples 0
Name: Charlie 3

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

qiiiiiiiip의 이미지

unix의 명령어 중 join 이 하는 일과 유사합니다.
먼저 입력파일이 아래 조건에 맞아야합니다.
1. 일단 스트링에 공백이 있으므로 field separator는 tab 으로 합니다.
2. key가 되는 field가 정렬되어있지 않으면 이중루프가 필요하므로 미리 소트를 합니다.

$ sort -k 2 a.txt > a.txt.sorted
$ sort b.txt > b.txt.sorted
$ cat a.txt.sort
1       Hello, world
2       I have a dog.
3       Name: Charlie
$ cat b.txt.sort
11 apples
Hello, world
I have a dog.
Name: Charlie
$ join -t $'\t' -1 2 -2 1 -a 2 -e 0 -o "2.1,1.1" a.txt.sort b.txt.sort
11 apples       0
Hello, world    1
I have a dog.   2
Name: Charlie   3

qiiiiiiiip의 이미지

사용하신 awk 스크립트를 수정해서 하려면 아마도 이런코드가 될 듯요.

$ awk -F '\t' 'FNR==NR{a[$2]=""$1;next};{print $1 "\t" int(a[$1])}' a.txt b.txt
Hello, world    1
I have a dog.   2
11 apples       0
Name: Charlie   3

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.