Jika semua perintah dan argumen Anda tidak mengandung #
, dan satu karakter lainnya (misalnya karakter ASCII yang diberikan oleh byte 1), Anda dapat memasukkan karakter lain tersebut sebagai pemisah tambahan dan menggunakan column
untuk menyelaraskan komentar (lihat jawaban ini). Jadi, sesuatu seperti:
$ 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
Jika column
Anda tidak mendukung -e
untuk menghindari penghapusan baris kosong, Anda dapat menambahkan sesuatu ke baris kosong (misalnya, spasi, atau karakter pemisah yang digunakan di atas):
$ 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
Pemrosesan teks dengan shell saja agak canggung dan mungkin rawan kesalahan (lihat "Mengapa menggunakan loop shell untuk memproses teks dianggap sebagai praktik yang buruk?"). Biasanya lebih baik menggunakan dan bahasa pemrograman lain untuk tugas-tugas seperti ini.
perl -ne 'if (/^([^#]+?)\s*#(.*)$/) { printf("%-16s#%s\n", $1, $2) } else { print }' file
Ini menggunakan Perl untuk menangkap bit di depan #
(buang spasi antara kata terakhir dan #
) dan bit setelahnya. Jika pencocokan berhasil, itu mengalokasikan 16 lokasi karakter untuk teks dan mencetak teks dan komentar yang diformat. Jika pencocokan tidak berhasil (karena baris kosong atau dimulai dengan #
), garis dicetak tanpa modifikasi.
# 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
Inilah skrip Python yang harus melakukan apa yang Anda inginkan:
#!/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)
Jalankan seperti ini:
python align.py input.txt
Ini menghasilkan output berikut:
# 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