Deleting columns passed as arguments to the script

Hi all,

I am trying to delete columns in a file using a script. The columns that need to be deleted are passed as arguments to the script.

The script should look like this

> delete_columns.sh <file_name.txt> <column_numbers_to_be_deleted>

The contents of the file_name.txt will be like

abcd
cdef
opqr

On running the script with the following arguments

> delete_columns.sh file_name.txt 4 2

the output should look like

ac
ce
oq

I wrote the following script which works with as mentioned

# This for loop removes the first argument i.e., file_name and keeps the remaining arguments in the shell variable columns_num_list
# So in the above example if arguments passed are file_name.txt 4 2
# the variable content after for loop will be columns_num_list="2,4"

for (( i = 2; i <= $#; i++ ))
do

	if [ $i -eq 2 ] 
	then 
		columns_num_list="${!i}"
	else
		columns_num_list="${!i},"$columns_num_list
	fi
done

# This command deletes the columns mentioned by columns_num_list variable
# This translates to cut --complement -c2,4 file_name.txt > file_with_columns_removed.txt

cut --complement -c$columns_num_list  $1 > file_with_columns_removed.txt

The issue is that the person who is using this script doesn't have

 --complement 

option to cut command. So this script is not useful.

I have tried to explore other options like awk and couldn't actually get much headway.

Please help me in resolving this issue.
Also I am at a very beginner level in bash scripting and trying to learn. So any suggestions to improve the code that I wrote(with --complement option) would be appreciated.

P.S. As an initial try using awk, I tried to split the input file into columns using nothing as field seperator like

awk -F=""

but the version of awk that I have isn't interpreting it correctly.(I know it is pretty much screwed up if I have old versions of commands without features :o . But what to do. Our IT team isn't willing to update to latest linux :wall: )

Thanks a lot
Regards
VNR

you can specify column to print rather than column to delete and make code more simpler:

awk -F"" '{print $1$3}'  infile

Yes, but this doesn't allow the columns to be specified dynamically. Something like the code below (provided your awk supports the -v option) will work:

awk -F "" -v collist="$columns_num_list" '
    BEGIN { OFS=""; ncol = split( collist, cols, "," ); }
    {
        for( i = 1; i <= ncol; i++ )
            $(cols) = "";
        print;
    }
'  file_name.txt >new-file

1 Like

That worked. Thanks a lot.

[root@dist unix]# cat file
abcd
cdef
opqr
[root@dist unix]# bash dele.sh 1 3
bd
df
pr
[root@dist unix]# bash dele.sh 2 4
ac
ce
oq
[root@dist unix]# cat dele.sh 
#!/bin/bash
while read i
do
     
     A=($(echo "${i}" | awk -F "" '{print $1,$2,$3,$4}'))
     a=$(((($(($1%2))==0))?0:1))
     b=$(((($(($2%2))==0))?2:3))
     echo "${A[$a]}${A[$b]}"
done <file
 
But this scipt  not comprehensive.

How about cut?

cut -c1,3 filename

With cut you can also specify a range, so to get characters 1 to 5, then 7 to 15 and 19 to 84, you could specify:-

cut -c1-5,7-15,19-84 filename

I hope that this helps.

Robin
Liverpool/Blackburn,
UK