Is there a simple way I can echo a file, skipping the first and last lines? I was looking at piping from head
into tail
, but for those it seems like I would have to know the total lines from the outset. I was also looking at split
, but I don't see a way to do it with that either.
5 Answers
Just with sed
, without any pipes :
sed '1d;$d' file.txt
NOTE
1
mean first lined
mean delete;
is the separator for 2 commands$
mean last line
More readable:
sed -e '1d' -e '$d' file.txt
You don't need to know the number of lines in advance. tail
and head
can take an offset from the beginning or end of the file respectively.
This pipe starts at the second line of the file (skipping the first line) and stops at the last but one (skipping the final line). To skip more than one line at the beginning or end, adjust the numbers accordingly.
tail -n +2 file.txt | head -n -1
doing it the other way round, works the same, of course:
head -n -1 file.txt | tail -n +2
-
I don't know why, but
head -n -1
removes the first AND the last line of my.txt
file, on Ubuntu 14.04.2LTS. Dec 22, 2015 at 23:20 -
1
-
head -n -1
works with GNU coreutils, maybe MacOS has some BSD variant? Nov 5, 2020 at 13:06 -
Thank you! Combination of tail and head lets you select exactly the lines you need - just sweet!– Kia KahaJul 22, 2021 at 13:00
Here is how to do it with awk
:
awk 'NR>2 {print t} {t=$0}'
Also another way for sed
:
sed '1d;x' file.txt
x
is advanced sed
command, it switches current line with the previous one: current goes into the buffer and previous goes to the screen and so on while sed
processing stream line by line (this is why the first line will be blank).
awk
solution on each step (line) puts current line into the variable and starts printing it out only after the second line is passed by. Thus, we got shitfed sequence of lines on the screen from the second to the last but one. Last line is omitted becasue the line is in the variable and should be printed only on the next step, but all steps already run out and we never see the line on the screen.
Same idea in the perl
:
perl -ne 'print $t if $.>2 ; $t=$_' file.txt
$.
stands for line number and $_
for current line.
perl -n
is shortcut for while(<..>) {..}
structure and -e
is for inline script.
For Mac users:
On Mac, head -n -1
doesn't work. Instead, reverse the file, chop off the first line, then reverse it back:
tail -r file.txt | tail -n +2 | tail -r
Explanation:
tail -r
: reverses the order of lines in its inputtail -n +2
: prints all the lines starting from the second line in its input
-
-
2On Mac, you could install "coreutils" using "brew install". It allows you to use GNU commands. You just need to add 'g' add the beginning of the command. For example: instead of "head", type "ghead". Feb 23, 2021 at 23:25
In python i would do like this.
#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
L = []
for line in f:
line = re.sub(r'\n', r'', line)
L.append(line)
print('\n'.join(L[1:-1]))
Paste the above code into a file and name it as script.py
. Run the script against the file you want to check with.
python3 script.py /path/to/the/file
Example:
$ cat file
foo
apple
banana
bar
$ python3 script.py file
apple
banana
-
1
''.join(list(open("/path/to/file"))[1:-1])
: This seems to be a simpler solution :-) And if you need it to be done on the command prompt directly, then you could try :python -c 'print("".join(list(open("/path/to/file"))[1:-1]))'
Jan 9, 2021 at 12:37