Sed:删除csv文件中的相同值

时间:2017-02-10 15:23:45

标签: csv awk sed

我有一个.csv文件,其中两列[A,B]仅包含数字。 B列是'#34;更长"。

我想从B列中删除A列中的每个数字。

示例:

A B
1 1
4 2
5 3
  4
  5

数字1,4,5应从B列中删除,因为它们存在于A列中。

谢谢。

2 个答案:

答案 0 :(得分:1)

鉴于此空格分隔文件:

$ cat file
A B
1 1
4 2
5 3
  4
  5

awk

awk 'NR==FNR {col1[++c1cnt]=$1; set[$1]; next} 
     $1 in set {  next }
     {col2[++c2cnt]=$1}
     END {
         m=(c1cnt<c2cnt) ? c2cnt : c1cnt
         for (i=1; i<=m; i++){
              printf "%s\t%s\n", col1[i], col2[i]
         }
     }' <(awk 'NF==1  && /^[[:space:]]/ {next} {print $1}' /tmp/file) <(awk 'NF==2 {print $2; next} /^[[:space:]]/ {print $1}' /tmp/file)
A   B
1   2
4   3
5   

答案 1 :(得分:0)

@ Sergiof4:尝试:

awk 'BEGIN{
            print "A B"
      }
 FNR==NR && FNR>1 && $0 !~ /^[[:space:]]+/{
                                            A[$1]=$1;
                                            C[++i]=$1;
                                            next
                                          }
 FNR!=NR && FNR>1{
                    if(!A[$2]){
                                    ++k;
                                    B[k]=$2
                              }
                 }
 END{
            for(j=1;j<=i;j++){
                                    print C[j] FS B[j]
                             }
    }
'   Input_file  Input_file

上面的代码是读取Input_file 2次。我将在短期内补充说明。

EDIT2:现在也为上述代码添加说明。

awk 'BEGIN{                                                       ##### starting BEGIN section here.
                print "A B"                                       ##### printing the hearders now.
          }
     FNR==NR && FNR>1 && $0 !~ /^[[:space:]]+/{                   ##### FNR(is a built-in awk's keyword which tells us number of lines in a Input_file, it gets RESET whenever it reads a new Input_file), NR(is also same as FNR only difference between them is NR's value will be keep on incressing till all Input_files are being read.). FNR==NR condition will be TRUE when first Input_file is being read. FNR>1 makes sure we are not reading header here. 0 !~ /^[[:space:]]+/ makes sure that our lines is not starting from space considering here we have only 2 fields in each line and empty space in starting of the line means it is having 1 field only in that line and do not want to have those lines(assumption here).
                                                A[$1]=$1;         ##### creating an array A here whose index is $1 and it's value is $1, where $1 is the first field of each line of Input_file which is currently being read.
                                                C[++i]=$1;        ##### creating an array C whose index is variable i whose value is incrementing each time above condition becomes TRUE and it's value is $1 of current line of Input_file.
                                                next              ##### next is awk's in-built keyword which skips all next statements of this program.
                                              }
     FNR!=NR && FNR>1{                                            ##### This condition will be TRUE only when 2nd time Input_file is being read and it's current line is not first line.
                        if(!A[$2]){                               ##### Checking if array A's value is NOT existing whose index is $2 of current line.
                                        ++k;                      ##### increasing the variable k's value to 1 each time.
                                        B[k]=$2                   ##### Assigning the array B's value to $2 whose index is variable k.
                                  }
                     }
     END{                                                         ##### Starting END section for awk program now.
                for(j=1;j<=i;j++){                                ##### Starting a loop which starts from j=1 to till variable i's value.
                                        print C[j] FS B[j]        ##### printing the values of array C and B which have their indexes as j.
                                 }
        }
    ' file35   file35                                             ##### Mentioning the Input_file 2 times here as reading the Input_file 2 times.

EDIT3:添加一个解决方案,即使一行中只有一个字段,也应该选择它。最初我认为不应该选择它,所以我没有添加那个逻辑代码。

awk 'BEGIN{
                print "A B"
          }
     FNR==NR && FNR>1{
                        A[$1]=$1;
                        C[++i]=$1;
                        next
                     }
     FNR!=NR && FNR>1{
                        if(!A[$2]){
                                        ++k;
                                        B[k]=$2
                                  }
                     }
     END{
                for(j=1;j<=i;j++){
                                        print C[j] FS B[j]
                                 }
        }
    '    Input_file  Input_file