结合来自awk的sed

时间:2013-10-17 09:36:24

标签: bash sed awk

我有一个包含多个部分的文本文件,我想更改其中一个部分中的内容(在我的案例中为## 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

有效。但正如你所看到的那样,它非常难看,并且还有一个不必要的步骤,我创建了多个临时文件。

我试图看看我是否可以改进这一点,而且我遇到的一个想法是,如果我能以某种方式从sed调用awk,那么我就可以远离创建临时文件。< / p>

所以我的问题是如何从sed致电awk?如果没有,我有办法改进这个脚本并远离创建那些临时文件。

请注意,我希望此脚本在Ubuntu和mac中都能正常工作。感谢。

更新

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

开头

更新2

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

我真诚地道歉,因为我没有事先解释所有的案件。

3 个答案:

答案 0 :(得分: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. 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

答案 1 :(得分: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

答案 2 :(得分: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