GNU/Linux >> Tutoriels Linux >  >> Linux

Lum - Comment formater la sortie Sed comme l'impression formatée de Printf?

Sed peut-il remplacer le texte par une chaîne formatée comme l'impression formatée de printf ?

La commande sed suivante remplace une ligne commençant par la valeur actuelle de « $domain » par plusieurs valeurs spécifiées dans des variables.

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

Cependant, la sortie ne sera pas correctement alignée car la longueur des valeurs de domaine, etc. n'est pas la même.

Donc, la sortie serait quelque chose comme

#oracle   hard   nproc    131072
oracle   hard   nproc    666

Bien que valide, il est difficile à lire. Je préférerais obtenir quelque chose comme

#oracle   hard   nproc    131072
oracle   hard   nproc    666

Le mieux que je puisse trouver pour obtenir le résultat souhaité est :

/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

Mais je crois qu'il doit y avoir une façon plus élégante de le faire.

Le document sed one liners contient quelques exemples qui utilisent un nombre spécifié de caractères, par exemple

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

Mais c'est dans l'regexp section pas dans le replacement rubrique.

Réponse acceptée :

Cela utilise la syntaxe regex étendue -r , ce qui élimine une grande partie de l'encombrement. De plus, comme vous connaissez déjà certaines des valeurs de champ, vous n'avez pas réellement besoin de les référencer, ce qui réduit à nouveau l'encombrement (et la surcharge).

& est une valeur de remplacement spéciale :elle contient l'intégralité du motif correspondant. Utilisation du & , réduit à nouveau l'encombrement. Comme il ne s'agit pas d'une référence arrière, il y a beaucoup moins de frais généraux.

J'ai utilisé ( +) vs ( *) . Le + suppose qu'il y a au moins un espace entre les champs d'entrée. Changez-le simplement en * ce n'est pas le cas.

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/" 

sortie

#oracle   hard   nproc    131072
oracle   hard   nproc    666

Linux
  1. Comment supprimer plusieurs lignes aléatoires d'un fichier texte à l'aide de Sed ?

  2. Comment se rappeler comment utiliser la redirection ?

  3. Comment créer une sortie virtuelle dans Pulseaudio ?

  4. Script Bash :comment affecter chaque sortie de ligne de commande à des valeurs dans un tableau ?

  5. tcpdump :comment obtenir une sortie grepable ?

Comment remplacer un disque dur sous Linux

Comment cloner une partition ou un disque dur sous Linux

COMMENT UTILISER L'EDITEUR SED

Tutoriel Unix Sed :comment écrire dans un fichier à l'aide de Sed

Je voudrais diriger la sortie de find dans la liste d'entrée de scp, comment?

Comment puis-je trier la sortie du -h par taille