如何在bash中的每個段落的開頭插入文本

如何在bash中的每個段落的開頭插入文本

我有一個包含由空白行分隔的多個段落的文件。從技術上講,它們不是段落,只是由空白行分隔的文字部分。

可以這麼說,我想透過在空行後面的每行第一行中插入一個數字來對段落進行編號。所以如果我的文件說:

這是文字。
這是更多文字。
甚至更多文字!

這是第二節中的文字。
更多文字。
你明白了...

我想讓它說:

1這是文字
這是更多文字
甚至更多文字!

2這是第二節中的文字。
更多文字。
你明白了...

答案1

使用 bash 內建指令嘗試:

#!/bin/bash

l=1                          # paragraph counter
echo -n $l                   # print paragraph counter without new line
while read x; do             # read current line from file, see last line
  if [[ $x == "" ]]; then    # empty line?
    echo                     # print empty line
    read x                   # read next line from file, see last line
    ((l++))                  # increment paragraph counter
    echo -n $l               # print paragraph counter without new line
  fi
  echo "$x"                  # print current line
done < file

答案2

一般來說,使用 shell 進行文字解析非常慢且麻煩。以下是一些其他選項:

  1. Perl 的“段落模式”

    perl -00pe 's/^/$./' file 
    

    解釋

    開啟-00段落模式,其中「行」由連續的 , 段落定義\n\n。將以目前「行」(段落)編號s/^/$./取代行的開頭 ( ) 。告訴perl 在執行由 給出的腳本後列印輸入檔的每一行。^$.-p-e

  2. awk

    awk -vRS='\n\n' -vORS='\n\n' '{print NR$0}' file
    

    解釋

    -vRS='\n\n'將 awk 的記錄分隔符號設定為連續的換行符號。與 Perl 的段落模式一樣,這使得它將段落視為「行」。然後我們告訴它列印當前行號 ( NR) 和當前「行」$0。將-vORS=輸出記錄分隔符設定為連續的換行符,以便在輸出中段落也由空白行分隔。請注意,這將在輸出末尾添加 2 個空白行。為了避免這種情況,您可以使用head

    awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2
    

作為比較,以下是在 10M 測試檔案上運行時,各種解決方案在我的系統上運行的時間:

$ time a.sh > /dev/null ## a.sh is Cyrus's solution

real    0m1.419s
user    0m1.308s
sys     0m0.104s

$ time perl -00pe 's/^/$./' file  > /dev/null 

real    0m0.087s
user    0m0.084s
sys     0m0.000s

$ time awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2 >/dev/null

real    0m0.074s
user    0m0.056s
sys     0m0.020s

正如您在上面看到的,perl 和 awk 解決方案都比 shell 方法快一個數量級。

相關內容