遵循给定规则缩进文本行

Din*_*ngo 2 text-processing text text-formatting

我想知道如何按照自定义规则递归地缩进越来越多的诗行。例如

假设我们有:

OF Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,
With loss of Eden, till one greater Man
Restore us, and regain the blissful Seat,
Sing Heav'nly Muse, that on the secret top
Of Oreb, or of Sinai, didst inspire
That Shepherd, who first taught the chosen Seed,
In the Beginning how the Heav'ns and Earth
Rose out of Chaos: Or if Sion Hill
Delight thee more, and Siloa's Brook that flow'd
Fast by the Oracle of God; I thence
Invoke thy aid to my adventrous Song,
That with no middle flight intends to soar
Above th' Aonian Mount, while it pursues
Things unattempted yet in Prose or Rhime.
And chiefly Thou O Spirit, that dost prefer
Before all Temples th' upright heart and pure,
Instruct me, for Thou know'st; Thou from the first
Wast present, and with mighty wings outspread.
Run Code Online (Sandbox Code Playgroud)

我们想要递归地缩进,在第一行之后的任意三行添加 3 个空格,这样

OF Mans First Disobedience, and the Fruit
   Of that Forbidden Tree, whose mortal tast
   Brought Death into the World, and all our woe,
   With loss of Eden, till one greater Man
Restore us, and regain the blissful Seat,
   Sing Heav'nly Muse, that on the secret top
   Of Oreb, or of Sinai, didst inspire
   That Shepherd, who first taught the chosen Seed,
In the Beginning how the Heav'ns and Earth
   Rose out of Chaos: Or if Sion Hill 
   Delight thee more, and Siloa's Brook that flow'd
   Fast by the Oracle of God; I thence
Invoke thy aid to my adventrous Song,
   That with no middle flight intends to soar
   Above th' Aonian Mount, while it pursues
   Things unattempted yet in Prose or Rhime.
And chiefly Thou O Spirit, that dost prefer
   Before all Temples th' upright heart and pure,
   Instruct me, for Thou know'st; Thou from the first
   Wast present, and with mighty wings outspread
Run Code Online (Sandbox Code Playgroud)

实现这一目标的最简单方法是什么?

ter*_*don 7

如果您只想缩进第一行,然后每第四行缩进一次,您可以使用awk


$ awk 'NR % 4 != 1{$0="    "$0};1' file 
OF Mans First Disobedience, and the Fruit
    Of that Forbidden Tree, whose mortal tast
    Brought Death into the World, and all our woe,
    With loss of Eden, till one greater Man
Restore us, and regain the blissful Seat,
    Sing Heav'nly Muse, that on the secret top
    Of Oreb, or of Sinai, didst inspire
    That Shepherd, who first taught the chosen Seed,
In the Beginning how the Heav'ns and Earth
    Rose out of Chaos: Or if Sion Hill
    Delight thee more, and Siloa's Brook that flow'd
    Fast by the Oracle of God; I thence
Invoke thy aid to my adventrous Song,
    That with no middle flight intends to soar
    Above th' Aonian Mount, while it pursues
    Things unattempted yet in Prose or Rhime.
And chiefly Thou O Spirit, that dost prefer
    Before all Temples th' upright heart and pure,
    Instruct me, for Thou know'st; Thou from the first
    Wast present, and with mighty wings outspread.
Run Code Online (Sandbox Code Playgroud)

或者perl

$ perl -pe 's/^/    / if $. % 4 != 1' file
OF Mans First Disobedience, and the Fruit
    Of that Forbidden Tree, whose mortal tast
    Brought Death into the World, and all our woe,
    With loss of Eden, till one greater Man
Restore us, and regain the blissful Seat,
    Sing Heav'nly Muse, that on the secret top
    Of Oreb, or of Sinai, didst inspire
    That Shepherd, who first taught the chosen Seed,
In the Beginning how the Heav'ns and Earth
    Rose out of Chaos: Or if Sion Hill
    Delight thee more, and Siloa's Brook that flow'd
    Fast by the Oracle of God; I thence
Invoke thy aid to my adventrous Song,
    That with no middle flight intends to soar
    Above th' Aonian Mount, while it pursues
    Things unattempted yet in Prose or Rhime.
And chiefly Thou O Spirit, that dost prefer
    Before all Temples th' upright heart and pure,
    Instruct me, for Thou know'st; Thou from the first
    Wast present, and with mighty wings outspread.
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,如果当前行号4 不等于 1,我们都会在行首添加 4 个空格,这意味着我们将对除第 1、第 4 等之外的所有行执行此操作。

在awk中,NR是行号,$0是该行的内容,因此 NR % 4 != 1{$0=" "$0};表示“当当前行号模4不等于1时,在行首添加4个空格”。最后的1;只是“print”的简写。

在 Perl 中,$.是当前行号,s/old/new/是替换运算符,它将替换第一次出现oldnew。So 的意思是“如果当前行号模 4 不等于 1,则用四个空格s/^/ / if $. % 4 != 1替换行 ( ) 的开头”。^意思是-p“在应用由”提供的脚本后打印输入文件的每一行-e

下面是完全相同的 perl 命令,但有更详细且更容易理解的版本:

perl -e '
open(my $fileHandle, "<", $ARGV[0]);
my $lineCount=0;

while(my $line = <$fileHandle>){
   $lineCount += 1;
   if ( $lineCount % 4 != 1 ){
       ## or $line = "    " . $line
       $line =~ s/^/    /
   }
   print "$line";
}' file
Run Code Online (Sandbox Code Playgroud)

或者,几乎相同:

perl -e '
open(my $fileHandle, "<", $ARGV[0]);
my $lineCount=0;

while(my $line = <$fileHandle>){
   $lineCount += 1;
   unless ( $lineCount % 4 == 1 ){
       $line = "    " . $line
   }
   print "$line";
}' file
Run Code Online (Sandbox Code Playgroud)

  • `awk '{print (NR % 4 == 1 ? "" : " ") $0}' file ` 会让我更有效率,因为它不会修改 $0,因此会强制进行字段分割,并且只有 1 个条件需要测试。测试正值(`==`)也比测试负值(`!=`)更清晰。 (2认同)