GNU/Linux >> Belajar Linux >  >> Linux

Perataan teks kompleks di bash

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

Linux
  1. Bagaimana Cara Menghapus Garis Duplikat Di Dalam File Teks?

  2. Bash Script:Periksa Apakah File Adalah File Teks?

  3. Ubah Surat Masuk Dari Teks/biasa Menjadi Teks/html?

  1. Ekstrak Teks Antara Dua Baris Tertentu?

  2. Hapus baris kosong dalam file teks melalui grep

  3. Skrip Bash mencetak Perintah Tidak Ditemukan pada baris kosong

  1. Hapus baris ganjil atau genap dari file teks

  2. gema teks dengan baris baru di bash

  3. Urutkan file teks dengan banyak baris sebagai satu baris