sed:在每N行之后插入一个字符串

sed:在每N行之后插入一个字符串,sed,Sed,我想在大文件中每隔30行插入一个字符串。我使用的是mini-sed,它不支持~(tilde)range操作符。我正在寻找sed唯一的解决方案。这将每3行插入一行 sed 'n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;s/$/\ string/' filename seq 1 10 | sed ': loop; n; n; a insert n; b loop' 生产 1 2 3 insert 4 5 6 insert

我想在大文件中每隔30行插入一个字符串。我使用的是mini-sed,它不支持~(tilde)range操作符。我正在寻找sed唯一的解决方案。

这将每3行插入一行

sed 'n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;s/$/\ 
string/' filename
seq 1 10 | sed ': loop; n; n; a insert
n; b loop'
生产

1
2
3
insert
4
5
6
insert
7
8
9
insert
10

调整
n的数量a
命令之前的code>命令

开始编辑

下面的初始解决方案在保持空间中需要与N行大小相同的内存。这是一个更好的解决方案,它只将
'\n'
保留在保留空间中,而不是保留所有行,需要的内存要少得多:

sed -e 'p;G;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;h;d;:insert;x;s/^.*$/new line/' your_large_file
可以使用比s命令更不为人所知的i命令执行相同的操作:

sed -e 'p;G;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;h;d;:insert;x;i \
new line
d' your_large_file
同样,可以使用
'sed-f script your_large_file'
运行的解释版本:

# Whatever happen afterward, the current line need to be printed.
p
# Append the hold space, that contains as much \n as the number of lines read since the text has been added.
G
# Keeps only the \n in the pattern space.
s/[^\n]//g
# The 't next' bellow is needed so the 't insert' will not take into account the s command above.
t next
:next
# If we have exaclty 5 \n in the patern space, empty the hold space and insert the text, else save the pattern space for next cycle.
# In both cases, end the current cycle without printing the pattern space.
s/^\n\{3\}$//
t insert
h
d
:insert
x
i \
new line
d
结束编辑

以下脚本将在每5行之后添加
'\n新行'
。如果您想每6行或100行执行一次,只需将
'\{5\}'
更改为
'\{6\}'
'\{100\}'

sed -n -e 'H;g;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;$ {x;s/^\n//;p};b;:insert;x;s/$/\nnew line/;s/^\n//;p' your_large_file
这值得一些解释,所以下面是一个注释脚本文件版本。它必须使用
“sed-n-f脚本您的\u大文件”
运行

H
g
# Now, the pattern and hold space contain what has been read so far with an extra \n at the beginning.
s/[^\n]//g
# Now, the pattern space only contains \n, the hold space is unmodified.
# The 't next' bellow is needed so the 't insert' will not take into account the s command above.
t next
:next
# If we have exactly 5 new lines in the pattern space, the hold space is printed without the \n at the beginning and with the text to added after 5 lines at its end.
s/^\n\{5\}$//
t insert
# If not 5 \n and at the last line, the hold space must be printed without the \n at its beginning.
$ {x;s/^\n//;p}
b
:insert
x
# Now the hold space is empty and ready to receive new lines as the pattern space has been emptied by the 2 s commands above.
s/$/\nnew line/
s/^\n//
p

这个线程是如何使事情过于复杂的另一个例子。这应该做到:

sed '0~30 s/$/string/g' < inputfile > outputfile
sed'0~30s/$/string/g'outputfile
每30行“字符串”插入到行的末尾。如果您想要一个带有“string”的新行,只需使用“\n string”。

使用

sed '1~30 i everyThirtyLine' file.dat

这是在Cygwin中测试的。

这将在每3行之后插入一行

[步骤101]#cat insert.sed
#在保留空间中再添加一个“x”
x
s/^/x/
t重置条件
:重置条件
#现在检查是否有3个'x'字符
s/x\{3\}//
x
t插入
B
:插入
a\
在此插入
[步骤102]#序号10 | sed-f insert.sed
1.
2.
3.
在此插入
4.
5.
6.
在此插入
7.
8.
9
在此插入
10
[步骤103]#

我肯定你有你的理由,但在这里很难不建议
awk
。实际上我不确定他有理由。@KarolyHorvath我肯定他有很多理由reasons@user1207217:启发我……嗨,谢谢。有较短的路吗。若要每100行插入一行,我希望避免100次指定“n”。@user868923,简短回答:不,此时您确实使用了错误的工具。您可以使用sed来构造n的字符串,然后运行它,但它将是一个sed命令,非常神秘,它实际上只会给其他向导留下好印象。嗯…“线程”这个词对堆栈溢出页来说永远都不合适。我同意你的观点,但你说的是“这个问题的其他答案”。:-)虽然这是我想要的,但询问者特别要求不使用tilde的解决方案。这不起作用:sed'0~5000 s/$/\n commit/g'batch-commit.sql sed:1:“0~5000 s/$/\n commit;/g”:无效的命令代码~可能对您来说太晚了,但我认为问题是您需要分隔分号-sed“0~5000 s/$/\n commit”/看看哪个更简单。:)