Сложное выравнивание текста в bash

Возможное решение: / usr / lib / virtualbox / vboxdrv.sh setup

Эта проблема, похоже, связана с последней версией VirtualBox. -5.0-5.0.6_103037_el7 установка / обновление (это часть обновления yum от 5.0.4 -> 5.0.6:

Cleanup    : VirtualBox-5.0-5.0.4_102546_el7-1.x86_64                                                                                       18/18 
warning: file /etc/rc.d/init.d/vboxweb-service: remove failed: No such file or directory

warning: file /etc/rc.d/init.d/vboxdrv: remove failed: No such file or directory

warning: file /etc/rc.d/init.d/vboxballoonctrl-service: remove failed: No such file or directory

warning: file /etc/rc.d/init.d/vboxautostart-service: remove failed: No such file or directory
6
14.05.2018, 21:51
3 ответа

Aquí hay un script de Python que debería hacer lo que quieras:

#!/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)

Ejecútalo así:

python align.py input.txt

Produce la siguiente salida:

# 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
3
27.01.2020, 20:20

Если все ваши команды и аргументы не содержат #, а один другой символ (представляет собой символ ASCII, заданный байтом 1 ), вы можете вставить этот другой символ в качестве дополнительного разделителя и использовать columnчтобы выровнять комментарии (см. этот ответ). Итак, что-то вроде:

$ 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

Если ваш columnне поддерживает -e, чтобы избежать удаления пустых строк, вы можете добавить что-нибудь к пустым строкам (, например, пробел или символ-разделитель, использованный выше):

$ 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
14
27.01.2020, 20:20

Обработка текста только с помощью оболочки немного неудобна и может быть подвержена ошибкам (см. " Почему использование цикла оболочки для обработки текста считается плохой практикой? " ). Как правило, для таких задач лучше использовать и другой язык программирования.


perl -ne 'if (/^([^#]+?)\s*#(.*)$/) { printf("%-16s#%s\n", $1, $2) } else { print }' file

Это использует Perl для захвата бита перед #(, отбрасывая пробелы между последним словом и#)и битом после. Если совпадение было успешным, он выделяет 16 символов для текста и печатает форматированный текст и комментарий. Если сопоставление (не было успешным, поскольку строка была пустой или начиналась с #), строка печатается без изменений.

# 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
5
27.01.2020, 20:20

Теги

Похожие вопросы