Bash 如何使用可能有新行的输入,每n个字符插入一个模式?
我试图使用sed每隔2000个字符向文件中插入一个模式。我正在使用这个sed命令,但是如果文件中有多行,它就不起作用,因为计数会在每一行上重置 模式:Bash 如何使用可能有新行的输入,每n个字符插入一个模式?,bash,perl,awk,sed,Bash,Perl,Awk,Sed,我试图使用sed每隔2000个字符向文件中插入一个模式。我正在使用这个sed命令,但是如果文件中有多行,它就不起作用,因为计数会在每一行上重置 模式:' ||“ sed "s/.\{2000\}/&'\n || '/g" file 如何使此命令与可能有或可能没有新行的输入一起工作?我同意非sed解决方案 下面是一个示例,它是每4个字符而不是每2000个字符插入一个模式 输入示例: aaaaaa bbbbbb 示例输出: aaaa' || 'aa b' || 'bbbb' ||
'
||“
sed "s/.\{2000\}/&'\n || '/g" file
如何使此命令与可能有或可能没有新行的输入一起工作?我同意非sed解决方案
下面是一个示例,它是每4个字符而不是每2000个字符插入一个模式
输入示例:
aaaaaa
bbbbbb
示例输出:
aaaa'
|| 'aa
b'
|| 'bbbb'
|| 'b
谢谢。这个
gnu awk
可以:
echo "abcdefghijkl" | awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%3==1) $i="\n ||"$i}1'
abc
||def
||ghi
||jkl
echo“abcdefghijkl”| awk-vfs=-vofs='{for(i=1;i1&&i%3==1)$i=“\n | |“$i}1”
abc
||def
||ghi
||jkl
对于您的文件,每1000个字符
awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%1000==1) $i="\n ||"$i}1' file
awk-vfs=-vofs='{for(i=1;i1&&i%1000==1)$i=“\n | |”$i}1”文件
更新的解决方案:
awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%4==1) $i="\x27\\n || \x27"$i;printf "%s\x27\\n || \x27",$0} END {print ""}' file
aaaa'\n || 'aa'\n || 'bbbb'\n || 'bb'\n || '
awk-vfs=-vofs='{for(i=1;i1&&i%4==1)$i=“\x27\\n | | \x27”$i;printf”%s\x27\\n | | \x27“,$0}END{print”“}文件
aaaa'\n | |'aa'\n | | |'bbbb'\n | | |'bb'\n | | |'
有一个特殊的Linux命令,用于按指定参数拆分文件
阅读有关csplit命令的详细信息。perl-0777pe“s/(.{2000})/\$1'\n | |'/gs”文件
将整个文件作为一行处理-0777
允许引用捕获不带shell的组,使其为空,因为我必须使用双引号\$1
使用s///gs
重复多次,并使用g
确保s
可以跨越换行符{4}
这里是一种通用的方法,我们可以给出要插入字符串的字符数。使用GNU
awk
的RS
,FS
,gsub
功能。使用GNUawk
进行测试,并且仅使用提供的示例。(好的,我刚刚测试了在5个字符后插入新字符,而且效果非常好:)
添加一种非线性形式的解决方案:
输出如下:
上述代码说明:添加上述代码的完整说明
awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" ' ##Mentioning noc=4 for number of characters after which we want to insert new character\
## , mentioning char variable with value which OP wants to insert. \
## Making RS NULL here, making FS as new line here for all lines of Input_file
{
num=num==noc?(noc-1):noc ##Creating variable num whose value is noc-1 when it is 4 and 4 when it is NOT 4.
gsub(".{"num"}","&" char) ##Using gsub function to give number of characters which need to be substitutes with new char here.
}
1 ##Mentioning 1 will print edited/non-edited line of Input_file.
' Input_file ##Mentioning Input_file name here.
GNU awk用于多字符RS,并且一次只将4个字符读入内存(与其他一些解决方案需要将整个文件一次读入内存不同):
以下sed解决方案将起作用(使用四个字符,而不是2000个字符): 说明:
将整个文件读入模式缓冲区(请参阅)H;1h;\$!Dx
在每四个字符后添加所需的文本s/\{4\}/&'\n| |'/g
\$
,因为替换模式包含单引号,所以使用双引号将sed字符串括起来更容易
编辑:如Ed Morton在评论中所述,与其使用双引号并转义$
,另一种方法是使用单引号并将每个嵌入的单引号'
替换为'\'
,以获得:
sed 'H;1h;$!d;x;s/.\{4\}/&'\''\n || '\''/g'
请将示例输入(无描述、无图像、无链接)和该示例输入的所需输出添加到您的问题中(无注释)。使用GNU sed,您可以使用
sed-z“s/\{2000\}/&'\n| |'/g”文件
。但是,换行符将被计为单独的字符。添加了示例输入@WiktorStribiżew解决方案运行完美,但遗憾的是,我的gnu版本是4.2.1,在4.2.2中添加了对-z的支持。更新了我的解决方案。PS您的输出中确实缺少ab
(应该是6b
)为什么您得到aa\nb'\n
没有4个字母?您能解释一下新行应该发生什么吗。计数应该从0开始,还是从前一行的剩余数字开始?使用八进制而不是十六进制来表示'
。看见此外,与发布的预期输出相比,最终脚本在'aa
之后缺少\nb
,并在输出的末尾显示一个额外的b'\n |
。@EdMorton感谢\047提示。OP多次更改请求,我已经放弃解决它。不客气,是的,我有一种感觉,可能就是这样!使用这种双重引用脚本的方法,您还需要转义代码>在设置了一些历史选项的某些Shell中。除非您需要双引号以避免陷入“逃逸”地狱-sed'H,否则在字符串和脚本周围始终使用单引号;1h;$!Dx;s/\{4\}/&\''''''\n | |'\''/g'文件
。当然,我并不建议您为此实际使用sed。很好,vsperl-0777
或sed-z
或awk-v RS=“”
当文件中没有空行时(如果有空行,这种方法将失败)或gawk-v RS='^$'
,我目前在任何答案中都没有看到,但可能会出现。
awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" '
{
num=num==noc?(noc-1):noc
gsub(".{"num"}","&" char)
}
1
' Input_file
aaaa'
|| 'aa
b'
|| 'bbbb'
|| 'b
awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" ' ##Mentioning noc=4 for number of characters after which we want to insert new character\
## , mentioning char variable with value which OP wants to insert. \
## Making RS NULL here, making FS as new line here for all lines of Input_file
{
num=num==noc?(noc-1):noc ##Creating variable num whose value is noc-1 when it is 4 and 4 when it is NOT 4.
gsub(".{"num"}","&" char) ##Using gsub function to give number of characters which need to be substitutes with new char here.
}
1 ##Mentioning 1 will print edited/non-edited line of Input_file.
' Input_file ##Mentioning Input_file name here.
$ awk -v RS='.{4}' '{printf "%s", (RT=="" ? $0 : RT "\047\n || \047")}' file
aaaa'
|| 'aa
b'
|| 'bbbb'
|| 'b
sed "H;1h;\$!d;x;s/.\{4\}/&'\n || '/g"
sed 'H;1h;$!d;x;s/.\{4\}/&'\''\n || '\''/g'