…这确实不是存在于每一行
标记行最大长度的示例|
,例如 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
使得
- 的最后一个字符
SPECIAL_WORD
应位于第 79 列,即行结束字符之前的最后一个字符 - if
SPECIAL_WORD
后跟除行结束字符之外的任何字符,该行不得被触及 - 如果包含的线
SPECIAL_WORD
已经超过允许的长度,则不得触摸该线,除非该线的左侧有足够的空间SPECIAL_WORD
SPECIAL_WORD
如果该行的最后一个字符与该行的第一个字符之间没有空格,则SPECIAL_WORD
不应触及该行 5-如果右对齐后的行长度SPECIAL_WORD
大于限制,则不应触及该行SPECIAL_WORD
可能包含多个单词,但应被视为一个单元SPECIAL_WORD
仅由 ASCII 字符组成。- 它始终是单行,不会出现换行符
SPECIAL_WORD
我尝试了常见的方法,如col
、column
、fmt
、format
、 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
。