add prefix to each column with sed

Viewed 80

I have a header and what to add the prefix "f4_" to each column.

I tried this:

echo -e  p.value"\t"beta | sed "s/\</f4_/g"

and got this:

f4_p.f4_value   f4_beta

I want this:

f4_p.value   f4_beta

I think the special character . in the header is messing this up but I am not sure how to fix

5 Answers

You can try this awk:

printf 'p.value\tbeta\n' |
awk 'BEGIN{FS=OFS="\t"}
{for (i=1; i<=NF; ++i) ($i != "") && $i = "f4_" $i} 1'

f4_p.value  f4_beta

For a no loop solution suggest you to use this gnu-awk solutiom:

printf 'p.value\tbeta\n' |
awk -v RS='[\t\n]+' 'NF{$0 = "f4_" $0} {ORS=RT} 1'

f4_p.value  f4_beta

You can add the prefix at the start or after TAB only with

echo -e  p.value"\t"beta | sed -E "s/^|\t/&f4_/g"
# => f4_p.value f4_beta

See the online demo.

Here,

  • -E enables POSIX ERE regex syntax
  • ^|\t - matches either start of a string or a TAB
  • & in the replacement puts back what was matched.

Since you want to add it to each column, you should add it after each column separator. In this case, the separator is \t:

$ echo -e  p.value"\t"beta | sed "s/\t/&f4_/g"
p.value f4_beta

(Here & means "the part s/// matched before," which will be \t)

This will miss, of course, the first column, so we add the beginning of line wildcard (^) to the matching regex. For that, we use the \| operator, which allows both of its sides to be matched:

$ echo -e  p.value"\t"beta | sed "s/^\|\t/&f4_/g"
f4_p.value  f4_beta

Use this Perl one-liner:

echo -e  p.value"\t"beta | perl -F'\t' -ane 'print join "\t", map { "f4_$_" } @F;'

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-a : Split $_ into array @F on whitespace or on the regex specified in -F option.
-F'/\t/' : Split into @F on TAB, rather than on whitespace.

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches

no need to loop the fields at all :

 printf 'p.value\tbeta\n' | 

 {m,g}awk 'gsub("[^\11]+",(__)"&")^_' FS='[\411]' __='f4_'
f4_p.value  f4_beta
Related