Text-Formatting

右對齊一行中的最後一個單詞

  • January 9, 2021

並非每行都存在

標記行的最大長度的範例|,例如 79 個字元,不包括行尾,並且SPECIAL_WORD是標題中提到的最後一個單詞:

Some words with(some = ! characters, beside ASCII) sdsdds                     |
Some words with(some = ! characters, beside ASCII)   SPECIAL_WORD             |
                                                                             |
Some words (some = ! characters, beside ASCII)  as  SPECIAL_WORD              |
Some words (some = ! characters, beside ASCII) asdb asd                       |
foobar blah SPECIAL_WORD                                                      |
eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII)| asdb asd SPECIAL_WORD
Some words (some = ! characters, be                                           |
Some words (some = ! characters, beSome words (some = ! characters, be SPECIAL|_WORD
Some words (some = ! characters, beside ASCII)  as  SPECIAL_WORD              |
                                                                             |
                                                                             |
Some words (some = ! characters, beside ASCII)  as                SPECIAL_WORD|
Some words (some = ! characters, beside ASCII)  as                   SPECIAL_W|ORD
Some words (some = ! characters, beside ASCII) asdb asd                       |
                                                                             |
Some words (some SPECIAL_WORD = ! characters, beside ASCII) asdb asd          |
                                                                             |

預期輸出:

Some words with(some = ! characters, beside ASCII) sdsdds                     |
Some words with(some = ! characters, beside ASCII)                SPECIAL_WORD|
                                                                             |
Some words (some = ! characters, beside ASCII)  as                SPECIAL_WORD|
Some words (some = ! characters, beside ASCII) asdb asd                       |
foobar blah                                                       SPECIAL_WORD|
eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII)| asdb asd SPECIAL_WORD
Some words (some = ! characters, be                                           |
Some words (some = ! characters, beSome words (some = ! characters, be SPECIAL|_WORD
Some words (some = ! characters, beside ASCII)  as                SPECIAL_WORD|
                                                                             |
                                                                             |
Some words (some = ! characters, beside ASCII)  as                SPECIAL_WORD|
Some words (some = ! characters, beside ASCII)  as                SPECIAL_WORD|
Some words (some = ! characters, beside ASCII) asdb asd                       |
                                                                             |
Some words (some SPECIAL_WORD = ! characters, beside ASCII) asdb asd          |
                                                                             |

相當混亂,不是嗎?我嘗試實施的規則是:

右對齊SPECIAL_WORD使得

  1. 的最後一個字元SPECIAL_WORD應位於第 79 列,即行尾字元之前的最後一個字元
  2. ifSPECIAL_WORD後跟除行尾字元之外的任何字元,則該行不應被觸及
  3. 如果包含的行SPECIAL_WORD已經超過允許的長度,則不得觸摸,除非左側有足夠的空間SPECIAL_WORD
  4. SPECIAL_WORD如果在沒有的行的最後一個字元和該行的第一個字元之間沒有空格,則SPECIAL_WORD不應觸摸 5- 如果右對齊後的行SPECIAL_WORD長度超過該行不應觸摸的限制
  5. SPECIAL_WORD可能包含多個單詞,但應被視為一個單元
  6. SPECIAL_WORD僅由 ASCII 字元組成。
  7. 它始終是單行,不會有換行符SPECIAL_WORD

我嘗試了常見的嫌疑人,如col, column, fmt, format, Bash’s printf,這裡列出的大多數想法(awk,簡短的 shell 腳本片段sed等),但一切都是某種“接近但沒有雪茄”。我已經降低了規則的嚴格性,所以我不得不放棄的其中一個功能/腳本現在可能會起作用,但是有太多的東西無法記住所有這些。

在我坐下來編寫一個完整的解析器之前,讓我在這裡問一下是否有更簡單的解決方案來解決我的問題。

由於正確堅持讓我發布我在這裡嘗試的內容是最接近的:

cat format_test  | perl -e 'my $len;foreach my $line ( <STDIN> ) {$line =~ /^$/ and print $line and next;$line =~ /^(.+?)( *?)(SPECIAL_WORD)?$/;$len = 79-(length($1));  printf("%s%${len}s\n", $1,$3);}'

cat用於明確輸入來自管道)

我向每一位 Perl 程序員致以最深切的歉意!

那個小可憎的輸出:


Some words with(some = ! characters, beside ASCII) sdsdds                      
Some words with(some = ! characters, beside ASCII)                 SPECIAL_WORD

Some words (some = ! characters, beside ASCII)  as                 SPECIAL_WORD
Some words (some = ! characters, beside ASCII) asdb asd                        
foobar blah                                                        SPECIAL_WORD
eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII) asdb asd eside ASCII) asdb asdSPECIAL_WORD
Some words (some = ! characters, be                                            
Some words (some = ! characters, beSome words (some = ! characters, beSPECIAL_WORD
Some words (some = ! characters, beside ASCII)  as                 SPECIAL_WORD


Some words (some = ! characters, beside ASCII)  as                 SPECIAL_WORD
Some words (some = ! characters, beside ASCII)  as                 SPECIAL_WORD
Some words (some = ! characters, beside ASCII) asdb asd                        

Some words (some SPECIAL_WORD = ! characters, beside ASCII) asdb asd

哪個適用於它不應該的線路。

使用perl, 並假設所有字元都是單寬度的:

perl -Mopen=locale -lspe '
 BEGIN{$pad = $width - 1 - length $word}
 s/(.*?)\s+\Q$word\E$/sprintf "%-*s %s", $pad, $1, $word/e
' -- -width=79 -word=SPECIAL_WORD < your-file

我可以為你寫,但不是免費的 :) 為了讓你開始,以下實施規則 3:

BEGIN { LEN=length(special_word)
       print "special word is", special_word
       print "LEN is", LEN }
$NF == special_word && length($0)<maxlength { print "PROCESSING: " $0; next }
                                           { print }

規則 5 需要一些天才,其他規則在我看來相當簡單。special_wordmaxlength是呼叫程序時必須設置的參數。如果程序在rightalign.awk中,您可以像執行它一樣awk -f rightalign.awk -v special_word=SPECIAL_WORD -v maxlength=80 inputfile

引用自:https://unix.stackexchange.com/questions/628105