Lum – How to sed output be formatted like printf’s formatted printing

columnssedtext processing

Can sed replace text with a string formatted like printf's formatted printing?

The following sed command replaces a line starting with the current value of "$domain" with several values specified in variables.

/bin/sed  "s/\(^${domain} *${limittype} * ${limititem}.*\)/$EXPL#\1\n${domain} ${limittype} ${limititem} ${value}/" /etc/security/limits.conf

However the output will not be properly aligned because the length of the values of domain etc. are not the same.

So the output would be something like

#oracle   hard   nproc    131072
oracle hard nproc 666

While valid, it is difficult to read. I would prefer to get something like

#oracle   hard   nproc    131072
oracle   hard   nproc    666

The best I can come with to get the desired output is:

/bin/sed  "s/\(^${domain}\)\( *\)\(${limittype}\)\( *\)\(${limititem}\)\( *\)\(.*\)/$EXPL#\1\2\3\4\5\6\7\n${domain}\2${limittype}\4${limititem}\6${value}/" /etc/security/limits.conf

But I believe there must a more elegant way to do this.

The sed one liners document contains some examples that use a specified number of characters, e.g.

sed -e :a -e 's/^.\{1,78\}$/ &/;ta'  # set at 78 plus 1 space

But this is in the regexp section not in the replacement section.

Best Answer

This uses the extended regex syntax -r, which clears up a lot of the clutter. Also, because you already know some of the field values, you don't actually need to back-reference them, again reducing clutter (and overhead).

& is a special replacement value: it hold the entire matched pattern. Using the &, again reduces clutter. As it is not a back-reference, it has significantly less overhead.

I've used ( +) vs. ( *). The + assumes that there is at least one space between input fields. Just change it to the * it that is not the case.

EXPL=
dom=oracle
typ=hard
itm=nproc
val=666

echo "oracle   hard   nproc    131072" |
  sed -r "s/^$dom( +)$typ( +)$itm( +).*/$EXPL#&\n$dom\1$typ\2$itm\3$val/" 

output

#oracle   hard   nproc    131072
oracle   hard   nproc    666
Related Question