Si toutes vos commandes et arguments ne contiennent pas #
, et un autre caractère (disons le caractère ASCII donné par l'octet 1), vous pouvez insérer cet autre caractère comme séparateur supplémentaire et utiliser column
pour aligner les commentaires (voir cette réponse). Donc, quelque chose comme :
$ sed $'s/#/\001#/' input-file | column -ets $'\001'
# Lines starting with # stay the same
# Empty lines stay the same
# only lines with comments should change
ls # show all major directories
# and other things
cd # The cd command - change directory
# will allow the user to change between file directories
touch # The touch command, the make file command
# allows users to make files using the Linux CLI # example, cd ~
bar foo baz # foo foo foo
Si votre column
ne prend pas en charge -e
pour éviter d'éliminer les lignes vides, vous pouvez ajouter quelque chose aux lignes vides (par exemple, un espace ou le caractère séparateur utilisé ci-dessus) :
$ sed $'s/#/\001#/;s/^$/\001/' input-file | column -ts $'\001'
# Lines starting with # stay the same
# Empty lines stay the same
# only lines with comments should change
ls # show all major directories
# and other things
cd # The cd command - change directory
# will allow the user to change between file directories
touch # The touch command, the make file command
# allows users to make files using the Linux CLI # example, cd ~
bar foo baz # foo foo foo
Le traitement de texte avec le shell seul est un peu gênant et peut être sujet aux erreurs (voir "Pourquoi l'utilisation d'une boucle shell pour traiter le texte est-elle considérée comme une mauvaise pratique ?"). Il est généralement préférable d'utiliser un autre langage de programmation pour des tâches telles que celles-ci.
perl -ne 'if (/^([^#]+?)\s*#(.*)$/) { printf("%-16s#%s\n", $1, $2) } else { print }' file
Cela utilise Perl pour capturer le bit devant le #
(en supprimant les espaces entre le dernier mot et le #
) et le peu après. Si la correspondance a réussi, il alloue 16 emplacements de caractères pour le texte et imprime le texte formaté et le commentaire. Si la correspondance a échoué (parce que la ligne était vide ou commençait par un #
), la ligne est imprimée sans modification.
# Lines starting with # stay the same
# Empty lines stay the same
# only lines with comments should change
ls # show all major directories
# and other things
cd # The cd command - change directory
# will allow the user to change between file directories
touch # The touch command, the make file command
# allows users to make files using the Linux CLI # example, cd ~
bar foo baz # foo foo foo
Voici un script Python qui devrait faire ce que vous voulez :
#!/usr/bin/env python
# -*- encoding: ascii -*-
"""align.py"""
import re
import sys
# Read the data from the file into a list
lines = []
with open(sys.argv[1], 'r') as textfile:
lines = textfile.readlines()
# Iterate through the data once to get the maximum indentation
max_indentation = 0
comment_block = False
for line in lines:
# Check for the end of a comment block
if comment_block:
if not re.match(r'^\s*#.*$', line):
comment_block = False
# Check for the beginning of a comment block
else:
if re.match(r'^[^#]*[^ #].*#.*$', line):
comment_block = True
indentation = line.index('#')
max_indentation = max(max_indentation, indentation)
# Iterate through the data a second time and output the reformatted text
comment_block = False
for line in lines:
if comment_block:
if re.match(r'^\s*#.*$', line):
line = ' ' * max_indentation + line.lstrip()
else:
comment_block = False
else:
if re.match(r'^[^#]*[^ #].*#.*$', line):
pre, sep, suf = line.partition('#')
line = pre.ljust(max_indentation) + sep + suf
comment_block = True
sys.stdout.write(line)
Exécutez-le comme ceci :
python align.py input.txt
Il produit la sortie suivante :
# Lines starting with # stay the same
# Empty lines stay the same
# only lines with comments should change
ls # show all major directories
# and other things
cd # The cd command - change directory
# will allow the user to change between file directories
touch # The touch command, the make file command
# allows users to make files using the Linux CLI # example, cd ~
bar foo baz # foo foo foo