![使用罗马数字对诗节进行编号](https://linux22.com/image/199718/%E4%BD%BF%E7%94%A8%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97%E5%AF%B9%E8%AF%97%E8%8A%82%E8%BF%9B%E8%A1%8C%E7%BC%96%E5%8F%B7.png)
我可以使用罗马数字对某首诗的任何节按顺序编号,如下所示:
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
(Search the wide world throughout) may well agree."
进入这个:罗马大写数字与节的最后一节对齐?
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
I While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
II She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
III Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
IV (Search the wide world throughout) may well agree."
我想知道是否有任何方法可以在 Linux 中使用文本实用程序来实现这一点。它可能不适合 awk,以罗马风格生成数字,但我已经在互联网上的某个地方找到了一个 bash 脚本来生成罗马数字
#/bin/bash
# roman.sh
#
# Function
#
num2roman() { # NUM
# Returns NUM in roman letters
#
input=$1 # input num
output="" # Clear output string
len=${#input} # Initial length to count down
roman_val() { # NUM one five ten
# This sub does the basic 'roman' algorythm
#
N=$1
one=$2
five=$3
ten=$4
out=""
case $N in
0) out+="" ;;
[123]) while [[ $N -gt 0 ]]
do out+="$one"
N=$(($N-1))
done
;;
4) out+="$one$five" ;;
5) out+="$five" ;;
[678]) out+="$five"
N=$(($N-5))
while [[ $N -gt 0 ]]
do out+="$one"
N=$(($N-1))
done
;;
9) while [[ $N -lt 10 ]]
do out+="$one"
N=$(($N+1))
done
out+="$ten"
;;
esac
echo $out
}
while [[ $len -gt 0 ]]
do # There are letters to add
num=${input:0:1}
# Do action according position
case $len in
1) # 1
output+="$(roman_val $num I V X)"
;;
2) # 10
output+="$(roman_val $num X L C)"
;;
3) # 100
output+="$(roman_val $num C D M)"
;;
*) # 1000+
# 10'000 gets a line above, 100'000 gets a line on the left.. how to?
num=${input:0:(-3)}
while [[ $num -gt 0 ]]
do output+="M"
num=$(($num-1))
done
;;
esac
input=${input:1} ; len=${#input}
done
echo $output
}
#
# Call it
#
num2roman $1
我使用以下语法调用:
for N in `seq 1 10`;do ./roman.sh $N; done
其输出是:
I
II
III
IV
V
VI
VII
VIII
IX
X
因此,从另一个角度来看,这可能只是从生成的罗马数字列表中挑选任何项目,然后将其中任何一个与任何节的最后一节对齐
答案1
在每个块之后在新行上打印记录号可能会更简单。如果您的空白行完全空白(即它们不是\n\n
) ,则可以使用\n \n
AWK 的“段落模式”(空字符串为):RS
function d2r(n, m) {
m = sprintf("%*s", int(n/1000), "")
gsub(/ /, "M", m)
return m r100[int(n%1000/100)] r10[int(n%100/10)] r1[int(n%10)]
}
BEGIN {
split("C,CC,CCC,CD,D,DC,DCC,DCCC,CM", r100, ",")
split("X,XX,XXX,XL,L,LX,LXX,LXXX,XC", r10, ",")
split("I,II,III,IV,V,VI,VII,VIII,IX", r1, ",")
RS = ""
}
{
print
print d2r(NR) " (" NR ")"
print ""
}
以上另存为roman_numeral_blocks.awk
$ printf '%s\n\n' foo bar | awk -f roman_numeral_blocks.awk
foo
I (1)
bar
II (2)
该" (" NR ")"
部分是为了让您可以验证d2r()
产生的正确结果。d2r()
尝试为给定的十进制数生成罗马数字。每 1000 个批次重复“M”。
如果您希望将数字打印在与块的最后一行相同的行上,那么您必须弄清楚如何保持原始缩进,以及当边距中的可用空间小于所需空间时该怎么办打印号码。
要将上述内容应用到 OP 示例,使用任何 POSIX awk,将是:
$ cat roman_numeral_blocks.awk
function d2r(n, m) {
m = sprintf("%*s", int(n/1000), "")
gsub(/ /, "M", m)
return m r100[int(n%1000/100)] r10[int(n%100/10)] r1[int(n%10)]
}
BEGIN {
split("C,CC,CCC,CD,D,DC,DCC,DCCC,CM", r100, ",")
split("X,XX,XXX,XL,L,LX,LXX,LXXX,XC", r10, ",")
split("I,II,III,IV,V,VI,VII,VIII,IX", r1, ",")
}
NR > 1 { prt(0) }
{ prev = $0 }
END { prt(1) }
function prt(isEnd, pfx) {
if ( (!NF || isEnd) && (match(prev, /[^[:space:]]/)) ) {
prev = substr(prev, RSTART)
pfx = sprintf("%-*s", RSTART-1, d2r(++numParas) " ")
}
print pfx prev
}
$ awk -f roman_numeral_blocks.awk file
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
I While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
II She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
III Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
IV (Search the wide world throughout) may well agree."
答案2
以下 perl 脚本使用 perl罗马模块。根据您使用的 UNIX 类型,这可能是为您的操作系统预先打包的。例如,在 Debian 以及 Ubuntu 或 Mint 等衍生产品上,您可以使用sudo apt-get install libroman-perl
.其他 Linux 发行版可能具有类似名称的软件包。否则,请使用以下命令安装它cpan
:
$ perl -MRoman -00 -ne '
@para = split /\n/, $_;
foreach my $l (0..$#para-1) {
$para[$l] = sprintf "%6s %s", "", $para[$l]
};
$para[$#para] = sprintf "%6s %s", roman(++$stanza), $para[$#para];
print join("\n", @para),"\n\n"' poem2.txt
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
i While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
ii She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
iii Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
iv (Search the wide world throughout) may well agree."
这会以段落模式读取文件(段落边界是一个或多个空行),将每个段落拆分为一个数组 ( @para
),并将@para 的最后一行缩进 8 个空格。 @para 的最后一行缩进了一个 6 字符的宽罗马数字(表示节号)和另外两个空格。然后打印该数组。
对于大写罗马数字,将uc
function 与roman()
function 一起使用 - 即替换第二行包含sprintf
:
$para[$#para] = sprintf "%6s %s", uc(roman(++$stanza)), $para[$#para];
如果您希望罗马数字左对齐,请使用%-6s
.例如
$para[$#para] = sprintf "%-6s %s", roman(++$stanza), $para[$#para];
或者
$para[$#para] = sprintf "%-6s %s", uc(roman(++$stanza)), $para[$#para];
答案3
使用乐(以前称为 Perl_6)
~$ raku -MMath::Roman -e '
my @para = .split( /^^ \h**7 "\n" /, :skip-empty ) given slurp;
for @para.kv -> $k,$v { "\n".print; for $v.lines.kv -> $l_key,$l_value {
put(sprintf( "%*s ", 5, "{to-roman($k+1) if $l_key == 7}") ~ "{$l_value.trim-leading}")
};};' Ariosto.txt
示例输入(直接从上面的OP帖子中复制粘贴):
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
(Search the wide world throughout) may well agree."
示例输出:
Injurious love, why still to mar accord
Between desires has been thy favourite feat?
Why does it please thee so, perfidious lord,
Two hearts should with a different measure beat?
Thou wilt not let me take the certain ford,
Dragging me where the stream is deep and fleet.
Her I abandon who my love desires,
I While she who hates, respect and love inspires.
Thou to Rinaldo show'st the damsel fair,
While he seems hideous to that gentle dame;
And he, who when the lady's pride and care,
Paid back with deepest hate her amorous flame,
Now pines, himself, the victim of despair,
Scorned in his turn, and his reward the same.
By the changed damsel in such sort abhorred,
II She would choose death before that hated lord.
He to the Pagan cries: "Forego thy theft,
And down, false felon, from that pilfer'd steed;
I am not wont to let my own be reft.
And he who seeks it dearly pays the deed.
More -- I shall take from thee yon lovely weft;
To leave thee such a prize were foul misdeed;
And horse and maid, whose worth outstrips belief,
III Were ill, methinks, relinquished to a thief."
"Thou liest," the haughty Saracen retorts,
As proud, and burning with as fierce a flame,
"A thief thyself, if Fame the truth reports:
But let good deeds decide our dubious claim,
With whom the steed or damsel fair assorts:
Best proved by valiant deeds: though, for the dame,
That nothing is so precious, I with thee
IV (Search the wide world throughout) may well agree."
上面的 Raku 代码对于预先存在的缩进相当稳健,并且split
可以调整代码以适应相邻节之间的不同间距,如下所述(如下)。
简而言之,使用正则表达式将诗歌文件slurp
插入段落split
中,该正则表达式查找模式 1)行首、2)七个水平空格和 3)换行符。 [如果分隔节的行确实为空,则用作正则表达式]。该函数被指示通过参数/副词删除空字符串,留下 4 个段落(即节)。段落用键值编号,首先传递到循环中,然后传递到嵌套循环中。在嵌套循环中,值(即文本)被分解为 (8) ,并用 0 到 7 进行编号(下面用于对每个节进行编号)。@para
/^^ \h**7 "\n" /
^^
\h**7
\n
/^^ $$ "\n" /
split
:skip-empty
kv
for
for
for
$v
lines
kv
打印是通过 完成的put
,它调用sprintf
将段落编号格式化$k+1
为字符串,后跟$l_value
(文本)字符串。字符串通过 . 连接起来~
。段落编号是使用三元素、最小宽度(右对齐)字符串格式化程序完成的:sprintf( "%*s ", 5, "{to-roman($k+1) if $l_key == 7}")
。条件if
仅在$l_key == 7
段落的第七行(零索引)上进行编号。由于缩进是用 完成的,因此需要使用 来修剪诗歌sprintf
的每一行,以便输出正确对齐。$l_value
trim-leading
最后,子程序使用在命令行中调用的模块将段落计数器to-roman(…)
转换$k+1
为罗马数字。 [事实上,后缀在这里也适用]。 Raku 模块可以在以下位置搜索Math::Roman
-M
(…)R
https://modules.raku.org并安装zef
,请参阅:https://github.com/ugexe/zef。
参考:
https://modules.raku.org/dist/Math::Roman:cpan:TITSUKI
https://raku.org