-1

I have to add two new columns at the end of the tab-delimited file with specific entries. My file looks like this

chr2 88861474 88861574 IGKJ2 chr2 88861170 88861270 IGKJ3 chr2 88860835 88860935 IGKJ4 chr2 88860517 88860617 IGKJ5 

Following is my expected output

chr2 88861474 88861574 IGKJ2 0 - chr2 88861170 88861270 IGKJ3 0 - chr2 88860835 88860935 IGKJ4 0 - chr2 88860517 88860617 IGKJ5 0 - 

I can make another file with 0 and - entries and using paste command i can merge the newly made file with my original file to get the desired output but I am looking for other options( using awk or sed)

1

5 Answers 5

4

In awk it would look something like this:

awk -v OFS='\t' '{print $0, "0", "-"}' inputfile 

OFS sets the output delimiter to tab, then just prints the desired fields after each line.

3

If your sed support \t in the replacement part of its s command, you can try

sed 's/$/\t0\t-/' inputfile 

If not and your shell supports the ksh93-style $'...' form of quotes:

sed $'s/$/\t0\t-/' inputfile 

If not, you can always do:

TAB=$(printf '\t') sed "s/\$/${TAB}0${TAB}-/" inputfile 
0

Using just bash:

#!/bin/bash while read line do printf "%s\t0\t-\n" "${line}" done < inputfile 
2
  • 2
    While that would work with the sample input shown, it'd corrupt other input (e.g. containing backslashes or null values in the first or last fields or printf formatting chars like %s) and it would be extremely slow, orders of magnitude slower than a more robust sed or awk script that could handle any input. Commented Mar 7, 2022 at 13:03
  • 1
    Yes, see also Why is using a shell loop to process text considered bad practice? Commented Mar 8, 2022 at 6:22
0

Method 1: Use a Perl one-liner:

perl -lpe '$_ = join "\t", $_, qw(0 -);' in_file > out_file 

Or change the file in-place:

perl -i.bak -lpe '$_ = join "\t", $_, qw(0 -);' in_file 

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-p : Loop over the input one line at a time, assigning it to $_ by default. Add print $_ after each loop iteration.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.

See also:

Method 2: Use paste and yes, without creating a temporary file:

paste in_file <( yes 0$'\t'- | head -n $( cat in_file | wc -l) ) > out_file 

This is a common method to add columns with constant values to a file. Unfortunately, it cannot change the file in-place. For that, you have to explicitly do this:

mv out_file in_file 

See also:

-1
awk 'BEGIN{OFS="\t"}{$(NF+1)="0\t-";print }' filename 

output

chr2 88861474 88861574 IGKJ2 0 - chr2 88861170 88861270 IGKJ3 0 - chr2 88860835 88860935 IGKJ4 0 - chr2 88860517 88860617 IGKJ5 0 - 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.