gnu sed - 删除前X行和后Y行之间的行

时间:2014-02-21 09:01:08

标签: bash sed

目标是缩短大文本:
删除前X行和最后Y行之间的所有内容 并且可能在中间插入一条如“截断到XY线的文件......”之类的线 我玩了很多次,用奇怪的重定向(Pipe output to two different commands),子壳, tee和多次sed次调用,我想知道是否

sed -e '10q'

sed -e :a -e '$q;N;11,$D;ba'
通过将两者合并为单个sed调用,可以简化

提前致谢

6 个答案:

答案 0 :(得分:2)

使用 head tail

(head -$X infile; echo Truncated; tail -$Y infile) > outfile

awk

awk -v x=$x -v y=$y '{a[++i]=$0}END{for(j=1;j<=x;j++)print a[j];print "Truncated"; for(j=i-y;j<=i;j++)print a[j]}' yourfile

或者如果正如您所说,输入来自管道,您可以使用 tee 进行流程替换:

yourcommand | tee >(head -$x > p1) | tail -$y > p2 ; cat p[12]

答案 1 :(得分:1)

你可以通过魔术咒语,流程替换和stdio重定向来实现:

x=5 y=8
seq 20 | { 
    tee >(tail -n $y >&2) \
        >({ head -n $x; echo "..."; } >&2) >/dev/null 
} 2>&1
1
2
3
4
5
...
13
14
15
16
17
18
19
20

此版本更顺序,输出应保持一致:

x=5 y=8
seq 20 | {
    { 
        # read and print the first X lines to stderr
        while ((x-- > 0)); do 
            IFS= read -r line 
            echo "$line" 
        done >&2
        echo "..." >&2  
        # send the rest of the stream on stdout
        cat - 
    } |
    # print the last Y lines to stderr, other lines will be discarded
    tail -n $y >&2
} 2>&1

答案 2 :(得分:0)

这是一个不需要知道文件长度的sed替代方案。

您可以将修改后的“head”表达式插入到“tail”表达式的滑动循环中。 E.g:

sed ':a; 10s/$/\n...File truncated.../p; $q; N; 11,$D; ba'

请注意,如果范围重叠,则输出中将出现重复的行。

示例:

seq 30 | sed ':a; 10s/$/\n...File truncated.../p; $q; N; 11,$D; ba'

输出:

1
2
3
4
5
6
7
8
9
10
...File truncated...
20
21
22
23
24
25
26
27
28
29
30

这是一个注释的多行版本,用于解释正在发生的事情:

:a                                   # loop label
10s/$/\n...File truncated.../p       # on line 10, replace end of pattern space
$q                                   # quit here when on the last line
N                                    # read next line into pattern space
11,$D                                # from line 11 to end, delete the first line of pattern space
ba                                   # goto :a

答案 3 :(得分:0)

如果您知道文件的长度

EndStart=$(( ${FileLen} - ${Y} + 1))
sed -n "1,${X} p
${X} a\\
 --- Truncated part ---
${EndStart},$ p" YourFile

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed '1,5b;:a;N;s/\n/&/8;Ta;$!D;s/[^\n]*\n//;i\*** truncated file ***' file

此处x=5Y=8

N.B。这样可以保留简短的文件。

答案 5 :(得分:0)

您还可以使用sed -u 5q(使用GNU sed)作为head -n5的无缓冲替代方案:

$ seq 99|(sed -u 5q;echo ...;tail -n5)
1
2
3
4
5
...
95
96
97
98
99