How to use sed to remove the last n lines of a file
I don't know about sed
, but it can be done with head
:
head -n -2 myfile.txt
Removing the new line in the last line of a text file using sed
This might work for you (GNU sed):
sed -z 's/\n\+$//' file
This will remove a newline(s) at the end of a file provided there are no null characters.
N.B. Normal use of sed i.e. without the -z
option which slurps the file into memory, will remove any newlines before the sed commands can act on them.
Remove the last line from a file in Bash
Using GNU sed
:
sed -i '$ d' foo.txt
The -i
option does not exist in GNU sed
versions older than 3.95, so you have to use it as a filter with a temporary file:
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
Of course, in that case you could also use head -n -1
instead of sed
.
MacOS:
On Mac OS X (as of 10.7.4), the equivalent of the sed -i
command above is
sed -i '' -e '$ d' foo.txt
How can I replace each newline (\n) with a space using sed?
Use this solution with GNU sed
:
sed ':a;N;$!ba;s/\n/ /g' file
This will read the whole file in a loop (':a;N;$!ba
), then replaces the newline(s) with a space (s/\n/ /g
). Additional substitutions can be simply appended if needed.
Explanation:
sed
starts by reading the first line excluding the newline into the pattern space.- Create a label via
:a
. - Append a newline and next line to the pattern space via
N
. - If we are before the last line, branch to the created label
$!ba
($!
means not to do it on the last line. This is necessary to avoid executingN
again, which would terminate the script if there is no more input!). - Finally the substitution replaces every newline with a space on the pattern space (which is the whole file).
Here is cross-platform compatible syntax which works with BSD and OS X's sed
(as per @Benjie comment):
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
As you can see, using sed
for this otherwise simple problem is problematic. For a simpler and adequate solution see this answer.
Delete second-to-last line of file using sed
This might work for you (GNU sed):
sed -i 'N;$!P;D' file
This sets up a window of two lines in the pattern space and then prints the first of those whenever the second is not the last. The last line is always printed because the next line can not be fetched.
Deleting the second-to-last line of a file based on a pattern can be achieved with:
sed -i 'N;$!P;${/pattern.*\n/!P};D'
Delete last character from line that contains specific word
This would do it:
sed '/in_bytes/ s/,$//'
Where /in_bytes/
is a search pattern ensuring only matching lines will execute the following command s/,$//
, which is a standard substitution to remove a trailing comma.
Example: https://ideone.com/3hEXBY
sed - remove line break if line does not end on \
give this awk one-liner a try:
awk '{printf "%s%s",$0,(/"$/?"\n":"")}' file
test
kent$ cat f
"foo"
"bar"
"a long
text with
many many
lines"
"lalala"
kent$ awk '{printf "%s%s",$0,(/"$/?"\n":"")}' f
"foo"
"bar"
"a longtext withmany manylines"
"lalala"
Delete third-to-last line of file using sed or awk
With tac
+ awk
solution, could you please try following. Just set line
variable of awk
to line(from bottom) whichever you want to skip.
tac Input_file | awk -v line="3" 'line==FNR{next} 1' | tac
Explanation: Using tac
will read the Input_file reverse(from bottom line to first line), passing its output to awk
command and then checking condition if line is equal to line(which we want to skip) then don't print that line, 1 will print other lines.
2nd solution: With awk
+ wc
solution, kindly try following.
awk -v lines="$(wc -l < Input_file)" -v skipLine="3" 'FNR!=(lines-skipLine+1)' Input_file
Explanation: Starting awk
program here and creating a variable lines
which has total number of lines present in Input_file in it. variable skipLine
has that line number which we want to skip from bottom of Input_file. Then in main program checking condition if current line is NOT equal to lines-skipLine+1
then printing the lines.
3rd solution: Adding solution as per Ed sir's comment here.
awk -v line=3 '{a[NR]=$0} END{for (i=1;i<=NR;i++) if (i != (NR-line)) print a[i]}' Input_file
Explanation: Adding detailed explanation for 3rd solution.
awk -v line=3 ' ##Starting awk program from here, setting awk variable line to 3(line which OP wants to skip from bottom)
{
a[NR]=$0 ##Creating array a with index of NR and value is current line.
}
END{ ##Starting END block of this program from here.
for(i=1;i<=NR;i++){ ##Starting for loop till value of NR here.
if(i != (NR-line)){ ##Checking condition if i is NOT equal to NR-line then do following.
print a[i] ##Printing a with index i here.
}
}
}
' Input_file ##Mentioning Input_file name here.
Related Topics
Script to Get User That Has Process with Most Memory Usage
Linux Kernel: Copy_From_User - Struct with Pointers
Why Do I Get /Etc/Cups Conflicts Between Attempted Installs in Yocto
Old Logs Are Not Imported into Es by Logstash
When Running Ls -L, Why Does the Filesize on a Directory Not Match the Output of Du
How to Prevent an X Window from Receiving User Input
Comparison of Cat Pipe Awk Operation to Awk Command on a File
Using Sed to Print Between Two Patterns
Git Shows Random Files Changed on MAC Nfs Filesystem
Terminal Closes When I Source My Script (Run with Dot at the Start)
How to Merge Similar Lines in Linux
Linux - Dependency Libmysqlclient.So.15 Not Found
How to Run a SQL Script in Tsql
How to Print Multiple Strings on New Line in the Assembly Language