简体   繁体   中英

Bash: remove all lines of input except last n lines

i want to remove all lines except n last or first n lines with a short one-liner

eg.:

---

aaaa

bbbb

cccc

dddd

cat/echo/find ...  | sed < all except last 2 lines > 

should result

aaaa

bbbb

---

aaaa

bbbb

cccc

dddd

eeee

ffff

cat/echo/find ...  | sed < all except last 2 lines > 

should result

aaaa

bbbb

cccc

dddd

---

I need this also for very high n´s. So it could possible to set n=100 or so ;)

Thanx for any help !

To remove the last 2 lines you can use something like this:

head -n $(($(wc -l < "$filename") - 2)) "$filename"

Not very elegant but it should work. I use wc -l to count the number of lines and then I use head to only display the first number of lines minus 2 lines.

EDIT: to keep only last N lines you could do

tail -n $N $filename

To keep only first N lines you could do.

head -n $N $filename

It seems I may have misunderstood your question and that is why I add these two commands.

From the head man page:

-n, --lines=[-]N
      print  the first N lines instead of the first 10; with the lead-
      ing ‘-’, print all but the last N lines of each file

which means ... | head -n -2 ... | head -n -2 will do what you want.

Just as an alternative, the following also works, though I imagine its efficiency is not at all good for large files.

tac file | awk 'NR>2' | tac

i want to remove all lines except n last

Easiest way is to do (let n=5):

tail -n5 $filename > $filename.tmp && mv $filename.tmp $filename

This will output last five lines to new file and than rename it.

If the task is opposite - you need all lines, but 5 last, you can to do:

head -n$((`cat $filename | wc -l` - 5)) $filename > $filename.tmp && mv $filename.tmp $filename

To keep last 1000 lines of a file (Ex: alert_PROD.log)

tail -1000 alert_PROD.log > alert_tmp ; cat alert_tmp > alert_PROD.log ; rm alert_tmp

To keep top 1000 lines use head instead of tail command:

head -1000 alert_PROD.log > alert_tmp ; cat alert_tmp > alert_PROD.log ; rm alert_tmp

要删除inputfile的最后3行:

set 3 inputfile; sed "$(($(sed -n $= $2)-$1+1)),\$d" $2

To print all but the first 3 and then all but the last 3 lines of a file:

$ cat -n file
     1  a
     2  b
     3  c
     4  d
     5  e
     6  f
     7  g
$ awk -v sz="$(wc -l < file)" 'NR>3' file      
d
e
f
g
$ awk -v sz="$(wc -l < file)" 'NR<=(sz-3)' file
a
b
c
d

You can use head and tail:

To remove all lines except first n lines:

head -n filename > new_filename

To remove all lines except last n lines:

tail -n filename > new_filename

Here is an example:

$ cat test

1

2

3

4

5

6

7

8

$ head -2 test

1

2

You could also try

awk -vn=2 -f rem.awk input.txt

where rem.awk is

BEGIN { ("wc -l " ARGV[1]) | getline 
    a=$1-n+1 }     
NR<a { print }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM