Problem Description
This is my file
1
2
3
4
5
6
7
8
9
10
I would like to send the cat output of this file through a pipe and receive this
% cat file | some_command
1
2
...
9
10
Attempted solutions
Here are some solutions I've tried, with their output
% cat temp | (head -n2 && echo '...' && tail -n2)
1
2
...
% cat temp | tee >(head -n3) >(tail -n3) >/dev/null
1
2
3
8
9
10
# I don't know how to get the ...
% cat temp | sed -e 1b -e '$!d'
1
10
% cat temp | awk 'NR==1;END{print}'
1
10
# Can only get 2 lines
CodePudding user response:
An awk:
awk -v head=2 -v tail=2 'FNR==NR && FNR<=head
FNR==NR && cnt ==head {print "..."}
NR>FNR && FNR>(cnt-tail)' file file
Or if a single pass is important, you can use perl
:
perl -0777 -lanE 'BEGIN{$head=2; $tail=2;}
END{say join("\n", @F[0..$head-1],("..."),@F[-$tail..-1]);}' file
Or, an awk that is one pass:
awk -v head=2 -v tail=2 'FNR<=head
{lines[FNR]=$0}
END{
print "..."
for (i=FNR-tail 1; i<=FNR; i ) print lines[i]
}' file
Or, nothing wrong with being a caveman direct like:
head -2 file; echo "..."; tail -2 file
Any of these prints:
1
2
...
9
10
CodePudding user response:
I suggest with bash
:
(head -n 2; echo "..."; tail -n 2) < file
Output:
1 2 ... 9 10
CodePudding user response:
You may consider this awk solution:
awk -v top=2 -v bot=2 'FNR == NR { n; next} FNR <= top || FNR > n-top; FNR == top 1 {print "..."}' file{,}
1
2
...
9
10
CodePudding user response:
Assumptions:
- as OP has stated, a solution must be able to work with stream from a pipe
One small modification to OP's 2nd entry under Attempted solutions:
# change this:
$ cat temp | tee >(head -n3) >(tail -n3) >/dev/null
# to this:
$ cat temp | tee >(head -n2; echo '...') >(tail -n3) >/dev/null
1
2
...
8
9
10
With parameterized head/tail
offsets:
$ h=2 t=3
$ cat temp | tee >(head -n${h}; echo '...') >(tail -n${t}) >/dev/null
1
2
...
8
9
10
CodePudding user response:
Two single pass sed
solutions:
sed '1,2b
3c\
...
N
$!D'
and
sed '1,2b
3c\
...
$!{h;d;}
H;g'