在从2到5的每一行的开头插入文本



我想在文件中每行的开头插入一个单词,后跟一个制表符(就地插入),但从第2行开始,直到最后5行。

因此,如果一个文件有10行,我想从第2行插入到第5行——在这种情况下,我想保持第1行和第6-10行不变。

文件的行数可能以百万计(目前高达1000万)

sed -i "s/^/wordt/" filename 

上面的工作,但我想插入的第一行和最后5行。同样给定一个行范围,计算行数将是另一项操作。由于线路编号可能会有所不同,因此这种额外的操作可能会成为一种开销。寻找有效的解决方案。以下是我迄今为止所尝试的:

COUNT=$((`wc -l test_csnap_delta.csv | cut -d ' ' -f 1` - 5))
sed -n -i '2,$COUNT s/^/wordt/' 

但是,上述操作将删除整个文件数据。

提前谢谢。

这在不预先计算文件中的行数的情况下工作:

sed -ni '1{p;b}; 2{N;N;N;N}; $p; $!{N;s/^/word /;P;D}' filename

这将缓冲五行,并在缓冲区的第一行进行替换,然后打印并删除它。当读取文件中的最后一行时,将打印缓冲区,而不进行任何替换。

  • 1{p;b}-读取第一行,打印不变并分支到末尾
  • 2{N;N;N;N}-读取第2行时,再追加四行以创建五行缓冲区
  • $p-读取文件的最后一行时,打印缓冲区中保持不变的行
  • $!-当当前行不是文件中的最后一行时
  • N-将下一行追加到缓冲区(模式空间)
  • s/^/word /-在缓冲区的第一行进行替换
  • P-只打印缓冲区中的第一行
  • D-只删除缓冲区中的第一行

请注意,对于包含少于6行的文件,这将无法正常工作。

这与使用AWK:的想法相同

awk 'FNR == 1 {print; next} FNR == 2 {for (ptr = 0; ptr <= 4; ptr++) {buffer[ptr] = $0; getline}; ptr = 0} {sub(/^/, "word ", buffer[ptr]); print buffer[ptr]; buffer[ptr] = $0; ptr = (ptr + 1) % 5} END {for (i = 0; i <= 4; i++) {print buffer[(ptr + i) % 5]}}' filename > outputfile
mv outputfile filename

在这里,它被分解为多行:

FNR == 1 {
print
next
}
FNR == 2 {
for (ptr = 0; ptr <= 4; ptr++) {
buffer[ptr] = $0
getline
}
ptr = 0
}
{
sub(/^/, "word ", buffer[ptr])
print buffer[ptr]
buffer[ptr] = $0
ptr = (ptr + 1) % 5
}
END {
for (i = 0; i <= 4; i++) {
print buffer[(ptr + i) % 5]
}
}

这样做:

LINES=`wc -l filename | awk '{print $1}'`
awk -v lines=$LINES 'NR > 1 && NR < lines-5 {$0 = "wordt" $0} {print}' filename

如果你想修改filename而不是将输出重定向到一个新文件,你需要一个临时文件和一些额外的代码来处理它:

mv filname tmpfile
LINES=`wc -l tmpfile | awk '{print $1}'`
awk -v lines=$LINES 'NR > 1 && NR < lines-5 {$0 = "wordt" $0} {print}' tmpfile 
> filename
rm tmpfile

基本上,就地编辑并不是最好的想法(进行就地编辑的程序通常也处理临时文件)。如果你对丑陋的细节感兴趣,可以看看这篇文章。

这可能适用于您(GNU sed);

sed -i '1b;:a;$q;N;2,6ba;s/^/wordt/;P;D' file

如果您有足够的RAM可用,您也可以尝试使用man 1 ed(有关ed的更多信息,请参阅:使用脚本中的ed文本编辑器编辑文件)。

# using Bash
str="$(printf '%sn' {1..10})"
tab="$(printf 't')"
# test
cat <<EOF | ed -s <(echo "$str")
H
2,$-5s/^/word${tab}/
,p
q
EOF
# in-place file editing
cat <<EOF | ed -s file
H
2,$-5s/^/word${tab}/
wq
EOF

最新更新