在每行的开头插入文本,从2到结尾 - 5

use*_*937 -1 bash awk sed

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

因此,如果一个文件有10行,我想从第2行插入到第5行 - 我希望在这种情况下保持第1行和第6-10行完好无损.

该文件可以有数百万行(目前高达1000万)

sed -i "s/^/word\t/" filename 
Run Code Online (Sandbox Code Playgroud)

以上工作,但我想插入第一行和最后5行.同样给出一个行范围,计算行数将是另一个操作.由于行号可以变化,因此这种额外的操作可能成为开销.寻找有效的解决方案.这是我到目前为止所尝试的:

COUNT=$((`wc -l test_csnap_delta.csv | cut -d ' ' -f 1` - 5))
sed -n -i '2,$COUNT s/^/word\t/' 
Run Code Online (Sandbox Code Playgroud)

但是,上面是删除整个文件数据.

提前致谢.

Pau*_*ce. 6

这不会妨碍文件中的行数:

sed -ni '1{p;b}; 2{N;N;N;N}; $p; $!{N;s/^/word /;P;D}' filename
Run Code Online (Sandbox Code Playgroud)

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

  • 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
Run Code Online (Sandbox Code Playgroud)

这里分为多行:

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]
    }
}
Run Code Online (Sandbox Code Playgroud)