2017-02-10 8 views
-1

У меня есть. CSV-файл с двумя столбцами [A, B], содержащий только числа. Столбец B «длиннее».Sed: удалять одинаковые значения в файле csv

Я хочу удалить из столбца B каждое число, которое находится в столбце A.

Пример:

A B 
1 1 
4 2 
5 3 
    4 
    5 

Числа 1,4,5 должны быть удалены из столбца B, так как они присутствуют в колонке A.

спасибо.

+0

Вы хотите, чтобы поле в столбце B было пустым после этого или если весь столбец сдвинут вверх, если происходит удаление? –

+0

Весь столбец сдвигается вверх, если происходит удаление. Спасибо. – Sergiof4

+0

было бы лучше, если бы вы могли добавить образец ввода/вывода, выделяя различные случаи, чтобы он мог быть протестирован. Также вы можете попытаться решить ... https://stackoverflow.com/documentation/sed/topics для начала – Sundeep

ответ

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 
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: Добавление раствора, где даже только 1 поле присутствует в линии, он должен быть выбран тогда. Первоначально я думал, что его не следует выбирать, поэтому я не добавил этот логический код.

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 
+1

1) Не читается; 2) Работает только на примере. Попробуйте 'A = 1,4,5 B = 1,2,3,4,5,6,7' – dawg

+0

@dawg: Спасибо вам или вашей обратной связи, позвольте мне исправить это. Для нечитаемого я писал, что это не одна линия, добавит ее сейчас. – RavinderSingh13

+0

@dwag: Я добавил не один вкладыш решения, а также объяснение кода, любезно дайте мне знать, могу ли я внести в него некоторые эффективные изменения. – RavinderSingh13