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
How to Run Multiple Programs in a Sequence
How to Add a System Call via a Lkm
How Can a Program Detect If It Is Running as a Systemd Daemon
Shuffle Output of Find with Fixed Seed
Why This Bash Function Prints Only First Word of Whole String
Why a Linux Redirect Truncates the File
Nginx Location Deny by File Extension Syntax
Listing Files Using a Variable Filter
How to Compile This Asm Code Under Linux with Nasm and Gcc
Why Does Script Not Recognize File Extension
Get the Pid of a Running Playbook for Use Within the Playbook
Django on Apache Wtih Mod_Wsgi (Linux) - 403 Forbidden
Rsync, 'Uid/Gid Impossible to Set' Cases Cause Future Hard Link Failure, How to Fix
Jupyter Lab - Suppress Console Output