如何使用SED更改多个文件中的第n行?

时间:2012-04-30 14:45:52

标签: bash sed

我有一系列文本文件要转换为markdown。我想删除任何前导空格并在每个文件的第一行添加一个井号。如果我运行这个:

sed -i.bak '1s/ *\(.*\)/\#\1/g' *.md

它改变了第一个文件的第一行并对它们进行了处理,剩下的文件保持不变。

我错过了哪些搜索和替换多个文件的第n行的内容?

在OSX 10.7上使用bash

3 个答案:

答案 0 :(得分:5)

问题是sed默认将任意数量的文件视为单个流,因此行号偏移量相对于第一个文件的开头。

对于GNU sed,您可以使用-s(--separate)标志来修改此行为:

sed -s -i.bak '1s/^ */#/' *.md

...或者,对于非GNU sed(包括Mac OS X上的那个),您可以遍历文件并每个调用一次:

for f in *.md; do sed -i.bak '1s/^ */#/' "$f"; done

请注意,这里的正则表达式有点简化 - 无需匹配您不会更改的部分行。

答案 1 :(得分:0)

XARgs会帮你解决问题:

http://en.wikipedia.org/wiki/Xargs

从sed命令的末尾删除* .md,然后使用XArgs一次收集一个文件并将它们作为单个实体发送到sed命令,抱歉我没有时间解决它对你而言,wikiPedia文章应该告诉你你需要知道什么。

答案 2 :(得分:0)

sed -rsi.bak '1s/^/#/;s/^[ \t]+//' *.md

你在命令的末尾不需要g(lobally),因为你不想在行的开头替换某些东西,而不是多次。

您使用两个命令,一个用于修改第1行(1s ...),使用分号从第二个命令中分离前导空白(以及制表符?:= \ t)。要删除第一行中的空格,请切换顺序:

sed -rsi.bak 's/^[ \t]+//;1s/^/#/' *.md

如果您不需要,请删除\ t。那么你也不需要一个小组:

sed -rsi.bak 's/^ +//;1s/^/#/' *.md

-r是表示正则表达式特殊处理的标志。在这种情况下,您不需要屏蔽加号。