Print words starting at particular positions

I have three words say abc def and ghi. I want to write them in a text file each starting (not ending) at particular positions say 1, 42 and 73. It is guaranteed that they will not overwrite.

Length of the three variable may vary.

Any help?

This would be simple in something like perl or python or even C, but shell doesn't support this directly.

You can abuse the dd utility to do this, though it's not the most efficient form of access.

printf "%s" "abc "| dd of=myfile bs=1 conv=notrunc seek=42

Untested, so back up your file before you try this.

Thanks. But this is not what I want. The output will be a single line consisting of values of abc, def and ghi starting at particular positions say 1, 42 and 73. (If I have to pring ending at those positions, printf command is handy). Use of awk is also fine.

a="abc"
b="def"
c="ghi"
printf "%-41s%-31s%s\n" $a $b $c

Read up on printf to see what is happening, but basically I am telling it to left-justify the strings in the fields of the given lengths.

Andrew

1 Like

Try this:

$ cat infile
test one
12345678901234567890123456789012345678901234567890123456789012345678901234567890
two

$ awk '
 BEGIN{
    R[1]="abc"
    R[42]="def"
    R[73]="ghi"
    w=75}
 { if(length<w) $0=sprintf("%-"w"s", $0);
  for(r in R) $0 = substr($0,1,r-1) R[r] substr($0,r + length(R[r]))}1' infile
abct one                                 def                            ghi
abc45678901234567890123456789012345678901def5678901234567890123456789012ghi67890
abc                                      def                            ghi

---------- Post updated at 09:45 AM ---------- Previous update was at 08:12 AM ----------

Another approach is to define a function to do the work and call it as required, the output of this solution should be the same as the earlier one, it just might be a little easier to read/change/comment:

awk '
function overlay(s,f,v) {return substr(sprintf("%-*s",length(v)+f,s),1,f-1) v substr(s,f+length(v)) }
{
 $0 = overlay($0,  1, "abc")
 $0 = overlay($0, 42, "def")
 $0 = overlay($0, 73, "ghi")
}1' infile
1 Like

Thanks apmcd47 and Chubler_XL. Works nice.