One-Liner: Print All Lines Except the Last 3

one-liner: print all lines except the last 3?

This works with a pipe as well as an input file:

seq 1 10 | perl -e'@x=<>;print@x[0..$#x-3]'

Perl one-liner prints everything except the last line

All I can say is...

It works on my computer!

(rimshot!)

So, exactly what are you getting? Is it an error message or does the program run? Does it print out any lines?

There is a difference between eof() and eof which might might be causing some of your concern (although both work on my system). According to Perldoc:

An eof without an argument uses the last file read. Using eof() with empty parentheses is different. It refers to the pseudo file formed from the files listed on the command line and accessed via the <> operator. Since <> isn't explicitly opened, as a normal filehandle is, an eof() before <> has been used will cause @ARGV to be examined to determine if input is available. Similarly, an eof() after <> has returned end-of-file will assume you are processing another @ARGV list, and if you haven't set @ARGV , will read input from STDIN ; see I/O Operators in perlop

By the way, the cat isn't needed. This is the same, and it saves you from creating an extra process:

perl -ne 'print if not eof()' < file

And, you should be able to do this:

perl -ne 'print if not eof()' file

Remove all lines except the last which start with the same string

Why don't you read the file from the end to the beginning and print the first line containing duplicate? This way you don't have to worry about what was printed or not, hold the line, etc.

tac file | awk '/duplicate/ {if (f) next; f=1}1' | tac

This sets a flag f the first time duplicate is seen. From the second timem, this flag makes the line be skipped.

If you want to make this generic in a way that every first word is printed just the last time, use an array approach:

tac file | awk '!seen[$1]++' | tac

This keeps track of the first words that have appeared so far. They are stored in the array seen[], so that by saying !seen[$1]++ we make it True just when $1 occurs for the first time; from the second time on, it evaluates as False and the line is not printed.

Test

$ tac a | awk '!seen[$1]++' | tac
this is a line
another unrelated line
duplicate but keep me
example but keep this one
more unrelated text

How to print all lines except the line before a pattern in file using awk

Here is one way with awk:

awk '/PATTERN/{for(;i<NR-2;)print lines[++i];i=NR;delete lines;print $0}{lines[NR]=$0}' file

Output:

$ cat file
Line 1
Line 2
####PATTERN####### (Line 3)
Line 4
Line 5
Line 6
####PATTERN####### (line 7)
Line 8
####PATTERN####### (Line 9)
$ awk '/PATTERN/{for(;i<NR-2;)print lines[++i];i=NR;delete lines;print $0}{lines[NR]=$0}' file
Line 1
####PATTERN####### (Line 3)
Line 4
Line 5
####PATTERN####### (line 7)
####PATTERN####### (Line 9)

Getting head to display all but the last line of a file: command substitution and standard I/O redirection

head is the wrong tool. If you want to see all but the last line, use:

sed \$d

The reason that

# Sample of incorrect code:
echo "hello" | head -n $(wc -l | sed -E -e 's/\s//g')

fails is that wc consumes all of the input and there is nothing left for head to see. wc inherits its stdin from the subshell in which it is running, which is reading from the output of the echo. Once it consumes the input, it returns and then head tries to read the data...but it is all gone. If you want to read the input twice, the data will have to be saved somewhere.

Print all lines except those matching a variable with awk

This is the standard inner join, except we print if a match was not found.

awk 'NR==FNR { a[$1]; next }
!($1 in a)' file1 file2 >newfile2

This is very standard Awk idiom all the way, but very briefly, the line number within the current file FNR will be equal to the overall input line number NR while we are traversing the first input file, file1. If so, we add its contents to the array a, and skip to the next line. Else, if we fall through, we are no longer in the first file; we print if the first field $1 is not in a.

Your original script would be more idiomatic and a lot more efficient phrased similarly (just without the !), too.

How to tail all lines except first row

tail -n+2 my_file

will output all the lines in myfile starting with line 2. (-n2 would show you the last two lines.)

tail has lots more options. Type man tail for complete documentation.



Related Topics



Leave a reply



Submit