Sed può sostituire il testo con una stringa formattata come la stampa formattata di printf?
Il seguente comando sed sostituisce una riga che inizia con il valore corrente di "$domain" con diversi valori specificati nelle variabili.
/bin/sed "s/\(^${domain} *${limittype} * ${limititem}.*\)/$EXPL#\1\n${domain} ${limittype} ${limititem} ${value}/" /etc/security/limits.conf
Tuttavia l'output non sarà allineato correttamente perché la lunghezza dei valori di dominio ecc. non è la stessa.
Quindi l'output sarebbe qualcosa del tipo
#oracle hard nproc 131072
oracle hard nproc 666
Sebbene valido, è difficile da leggere. Preferirei ottenere qualcosa come
#oracle hard nproc 131072
oracle hard nproc 666
Il meglio che posso trovare per ottenere l'output desiderato è:
/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
Ma credo che ci debba essere un modo più elegante per farlo.
Il documento sed one liners contiene alcuni esempi che utilizzano un numero specificato di caratteri, ad es.
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # set at 78 plus 1 space
Ma questo è nel regexp
sezione non nella replacement
sezione.
Risposta accettata:
Questo utilizza la sintassi regex estesa -r
, che elimina un sacco di disordine. Inoltre, poiché conosci già alcuni dei valori dei campi, non è necessario fare un riferimento a ritroso, riducendo nuovamente il disordine (e le spese generali).
&
è un valore di sostituzione speciale:contiene l'intero motivo abbinato. Usando il &
, riduce ancora il disordine. Poiché non è un back-reference, ha un sovraccarico notevolmente inferiore.
Ho usato ( +)
rispetto a ( *)
. Il +
presuppone che vi sia almeno uno spazio tra i campi di input. Basta cambiarlo in *
non è così.
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/"
uscita
#oracle hard nproc 131072
oracle hard nproc 666