Home > Mobile >  How to remove columns from a file by given the columns in anther file in Linux?
How to remove columns from a file by given the columns in anther file in Linux?

Time:12-19

Suppose I have a file A contains the column numbers need to be removed (I really have over 500 columns in my input file fileB),

fileA:

2
5

And I want to remove those columns(2 and 5) from fileB:

a b c d e f
g h i j k l

in Linux to get:

a c d f
g i j l

what should I do? I found out that I could eliminate printing those columns with the code:

awk '{$2=$5="";print $0}' fileB

however, there are two problems in this way, first it does not really remove those columns, it just using empty string to replace them; second, instead of manually typing in those column numbers, how can I get these column numbers by reading from another file.


Original Question: Suppose I have a file A contains the column numbers need to be removed,

file A:

223
345
346
567

And I want to remove those columns(223, 345,567) from file B in Linux, what should I do?

CodePudding user response:

$ cat tst.awk
NR==FNR {
    badFldNrs[$1]
    next
}
FNR == 1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr  ) {
        if ( !(inFldNr in badFldNrs) ) {
            out2in[  numOutFlds] = inFldNr
        }
    }
}
{
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr  ) {
        inFldNr = out2in[outFldNr]
        printf "%s%s", $inFldNr, (outFldNr<numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk fileA fileB
a c d f
g i j l

CodePudding user response:

If your cut have the --complement option then you can do:

cut --complement -d ' ' -f "$(echo $(<FileA))" fileB

CodePudding user response:

One awk idea:

awk '
FNR==NR { skip[$1] ; next }                # store field #s to be skipped
        { line=""                          # initialize output variable
          pfx=""                           # first prefix will be ""
          for (i=1;i<=NF;i  )              # loop through the fields in this input line ...
              if ( !(i in skip) ) {        # if field # not mentioned in the skip[] array then ...
                 line=line pfx $i          # add to our output variable
                 pfx=OFS                   # prefix = OFS for 2nd-nth fields to be added to output variable
              }
          if ( pfx == OFS )                # if we have something to print ...
             print line                    # print output variable to stdout
         }
' fileA fileB

NOTE: OP hasn't provided the input/output field delimiters; OP can add the appropriate FS/OFS assignments as needed

This generates:

a c d f
g i j l

CodePudding user response:

Using awk

$ awk 'NR==FNR {col[$1]=$1;next} {for(i=1;i<=NF;  i) if (i != col[i]) printf("%s ", $i);  printf("\n")}' fileA fileB
a c d f
g i j l
  • Related