1

私は2つのファイルを持っています。小さいものと大きいもの、大きいものには小さいもののすべての行が含まれています。これらの行はほとんど同じですが、最後の列だけが異なります。

file_smaller
  A NM 0
  B GT 4

file_bigger
  A NM 5 <-same as in file_smaller according to my rules
  C TY 2
  D OP 6
  B GT 3 <-same as in file_smaller according to my rules

2つのファイルが異なる行を書きたいのですが、これは次のことを意味します。

wished_output
  C TY 2
  D OP 6

私がそうするのを手伝ってくれませんか。どうもありがとう。

4

4 に答える 4

2

次のことができます。

cat file_bigger file_smaller |sed 's=\(.*\).$=\1='|sort| uniq -u > temp_pat
grep -f temp_pat file_bigger ; rm temp_pat

これは(同じ順序で)

  • ファイルをマージします
  • 最後の列を削除します
  • 結果を並べ替える
  • temp_patの一意の行のみを出力します
  • file_biggerで元の行を検索します

全体として、期待される結果。

于 2012-04-17T12:23:16.270 に答える
1
awk 'FILENAME==file_bigger {arr[$1 $2]=$0}
     FILENAME==file_smaller { tmp=$1 $2;  if( tmp in arr) {next} else {print $0}}
    ' file_bigger file_smaller

それがあなたのニーズを満たしているかどうかを確認してください

于 2012-04-17T12:31:36.470 に答える
1
grep -vf <(cut -d " " -f 1-2 file_smaller| sed 's/^/^/') file_bigger

プロセス置換の結果は次のようになります。

^A NM
^B GT

次に、grep -vそれらのパターンを「file_bigger」から削除します

于 2012-04-17T14:50:37.173 に答える
0

連想配列を使用したBash4:

#!/usr/bin/env bash

f() {
    if (( $# != 2 )); then
        echo "usage: ${FUNCNAME} <smaller> <bigger>" >&2
        return 1
    fi

    local -A smaller
    local -a x

    while read -ra x; do
        smaller["${x[@]::2}"]=0
    done <"$1"

    while read -ra x; do
        ((${smaller["${x[@]::2}"]:-1})) && echo "${x[*]}"
    done <"$2"
}

f /dev/fd/3 /dev/fd/0 <<"SMALLER" 3<&0 <<"BIGGER"
A NM 0
B GT 4
SMALLER
A NM 5
C TY 2
D OP 6
B GT 3
BIGGER
于 2012-04-17T12:45:42.480 に答える