右对齐一行中的最后一个单词

右对齐一行中的最后一个单词

…这确实不是存在于每一行

标记行最大长度的示例|,例如 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

我尝试了常见的方法,如colcolumnfmtformat、 Bash 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

这在它不应该起作用的线路上起作用。

答案1

使用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

答案2

我可以为你写这个,但不是免费的:)为了让你开始,下面实现了规则 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 需要一些天才,其他规则对我来说看起来相当简单。特殊词最长长度是调用程序时必须设置的参数。如果程序在右对齐.awk,你运行它就像awk -f rightalign.awk -v special_word=SPECIAL_WORD -v maxlength=80 inputfile

相关内容