1

我有一个包含多个部分的文本文件,我想更改其中一个部分(在我的情况下为## Screenshots ## 部分)中存在的内容,并使其他部分保持不变。

文件的一部分看起来像

3. line 3
4. line 4

## Screenshots ##

1. This is the first line

2. There could be blank lines like the one above and below.

3. Lines could contain special characters like ( # $ % etc and even quotes ""'` etc
5. Lines numbers need not be sequential.
4. Lines numbers could be in any order


## Changelog ##

3. line 3
4. line 4

它应该被修改为

3. line 3
4. line 4

## Screenshots ##

![](screeshot-1.png)
This is the first line

![](screeshot-2.png)
There could be blank lines like the one above and below.

![](screeshot-3.png)
Lines could contain special characters like ( # $ % etc and even quotes ""'` etc
![](screeshot-5.png)
Lines numbers need not be sequential.
![](screeshot-4.png)
Lines numbers could be in any order

## Changelog ##

3. line 3
4. line 4

我有以下脚本可以做到这一点。

awk '/^## Screenshots ##/ {f="screenshot.md";print > f;next} 
    f=="screenshot.md" && /^##/ {f="after_screenshot.md"} 
    {print > f}' f=before_screenshot.md readme.md

sed "/^[0-9]/s/\(^[0-9]*\)./\!\[\](screeshot-\1.png)\\`echo -e '\n\r'`/" screenshot.md > processed-screenshots.md

cat before-screeshots.md processed-screenshots.md after-screenshots.md > readme.md

有用。但是正如您所看到的,它非常难看,而且还有一个不需要的步骤,我在其中创建了多个临时文件。

我试图看看我是否可以改进这一点,我想到的一个想法是,如果我能以某种方式调用sedfrom awk,那么我就可以摆脱创建临时文件的麻烦。

sed所以我的问题是我如何打电话awk?如果没有,是否有办法改进此脚本并避免创建这些临时文件。

请注意,我希望这个脚本可以在 Ubuntu 和 mac 中运行。谢谢。

更新

一澄清。不同的部分不必总是以相同的顺序出现。在上面的示例屏幕截图中,后面是更改日志,但可能会更改。我们唯一知道的是,下一节也将从##

更新 2

另一个澄清。屏幕截图部分可能有空行,并且这些行并不总是 2 个单词。更新了示例文件。

对于没有事先解释所有极端案例,我深表歉意。

4

3 回答 3

4

一个简单的awk脚本:

BEGIN {                 # Set the field separator to a . for picking up line num
    FS="."
}
/^##/ {                 # If we hit the a new section stop
    flag = 0
}
flag && $1~/^[0-9]+/ {  # If the the flag is set and starts with number add text
    print "![](screeshot-" $1 ".png)"
    sub(/^[0-9]+ /,"")  # Remove the leading line number (no limit on fields)
}
/^## Screenshots ##$/ { # If we hit the screenshot section start
    flag=1
}
{                       # Print all the lines in the file
        print
}

将其保存到文件中,例如f.awk (可能更具描述性)并运行如下:

$ awk -f f.awk file

输出:

3. 3号线
4. 第 4 行

##截图##

![](screeshot-1.png)
这是第一行

![](screeshot-2.png)
上面和下面可能会有空行。

![](screeshot-3.png)
行可以包含特殊字符,例如 ( # $ % 等,甚至引号 ""'` 等
![](screeshot-5.png)
行号不必是连续的。
![](screeshot-4.png)
行号可以是任何顺序


## 变更日志##

3. 3号线
4. 第 4 行
于 2013-10-17T09:43:40.357 回答
3

你可以试试sed这个

sed -r '/## Screenshots ##/,/## Changelog ##/{s/^([0-9]+)\. (.*)/![](screenshot-\1.png)\n\2/g}' yourfile

如果你没有-r选择,

sed '/## Screenshots ##/,/## Changelog ##/{s/^\([0-9]\+\)\. \(.*\)/![]\(screenshot-\1.png\)\n\2/g}' yourfile
于 2013-10-17T09:43:13.573 回答
2

这一个班轮应该可以解决您的问题(通过您的更新)

awk '/^## Screen/{p=1;print;next}p&&/^##/{p=0}p&&$0{print "![](screenshot-"++i".png)";$0=$2FS$3}7' file

输出:

3. line 3
4. line 4

## Screenshots ##

![](screenshot-1.png)
line 1
![](screenshot-2.png)
line 2
![](screenshot-3.png)
line 3
![](screenshot-4.png)
line 4

## Changelog ##

3. line 3
4. line 4

编辑新示例:

awk '/^## Screen/{p=1;print;next}p&&/^##/{p=0}p&&$0{print "![](screenshot-"++i".png)";sub(/^\S* /,"")}7' file

输出:

3. line 3
4. line 4

## Screenshots ##

![](screenshot-1.png)
This is the first line

![](screenshot-2.png)
There could be blank lines like the one above and below.

![](screenshot-3.png)
Lines could contain special characters like ( # $ % etc and even quotes ""'` etc
![](screenshot-4.png)
line 4

## Changelog ##

3. line 3
4. line 4
于 2013-10-17T09:47:39.260 回答