SED: insert something after the second last line?
Solution 1
To insert a line before the last ($
) one:
$ cat test
one
two
three
four
five
$ sed '$i<hello>!' test
one
two
three
four
<hello>!
five
That's for GNU sed
(and beware leading spaces or tabs are stripped). Portably (or with GNU sed
, if you want to preserve the leading spaces or tabs in the inserted line), you'd need:
sed '$i\
<hello>!' test
Solution 2
Yes, sed
can be told to act on only a specific line by writing the line number before the operation you tell it to perform. For example, to insert a line with the string foo
after the 4th line of a file, you could do:
sed '4s/$/\nfoo/' file # GNU sed and a few others
sed '4s/$/\
foo/' file # standardly/portably
To insert a line after the next to last line, I can think of two approaches:
Count the number of lines first and then make the edit:
sed "$(( $( wc -l < file) -2 ))s/$/\nfoo/" file
Use
tac
:tac file | sed '2s/$/\nfoo/' | tac
Related videos on Youtube
Fractaliste
French IT engineer. Prefered language : Java Prefered framework : Laravel Prefered solver : Choco Prefered metasyntactic variable : plop Prefered quote : There are 10 kind of people on the world, those who understand binary, and those who don't. If needed, you can contact me on : fractaliste at gmail dot com
Updated on September 18, 2022Comments
-
Fractaliste over 1 year
In a XML configuration file I need to add a line, in order to not to break the last closing tag. Is it possible to do it with SED ?
The number of line of the whole file can change from a server to another...
Edit : Some exemple of file I need to edit :
<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
An other exemple:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="DEV_HOME" value="c:/logs" /> <appender name="FILE-AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${DEV_HOME}/debug.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{yyyy-MM-dd HH:mm:ss} - %msg%n </Pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily --> <fileNamePattern>${DEV_HOME}/archived/debug.%d{yyyy-MM-dd}.%i.log </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> </appender> <logger name="com.mkyong.web" level="debug" additivity="false"> <appender-ref ref="FILE-AUDIT" /> </logger> <root level="error"> <appender-ref ref="FILE-AUDIT" /> </root> <logger name="com.mkyong.ext" level="debug" additivity="false"> <appender-ref ref="FILE-AUDIT" /> </logger> <logger name="com.mkyong.other" level="info" additivity="false"> <appender-ref ref="FILE-AUDIT" /> </logger> <logger name="com.mkyong.commons" level="debug" additivity="false"> <appender-ref ref="FILE-AUDIT" /> </logger> </configuration>
-
Fractaliste about 7 years@StephenKitt You're right but I need tools included with Ubuntu12 because I can't install new tools on the server.
-
don_crissti about 7 yearsWhat a mess... Could you perhaps post a very short input sample and the expected output ?
-
Kusalananda about 7 yearsWhy can't you install tools on the server?
-
Fractaliste about 7 years@Kusalananda it's a secured environment and each tools to be installed have to be tested and validated by a dedicated team. It's more a corporate's process problen than an inability to install it.
-
Stephen Kitt about 7 yearsAnd yet you’re allowed to manipulate Log4J XML files directly on the server? O_O
-
Kusalananda about 7 yearsNotice that any script that comes out of here may be considered a tool that needs to be tested and validated too. Just saying.
-
-
Fractaliste about 7 yearsAs far as I understand I can't use the sed's -i option with
tac
? -
terdon about 7 years@Fractaliste no, not with
tac
, but you can always dotac file | sed '2s/$/\nfoo/' | tac > newfile && mv newfile file
-
Stéphane Chazelas about 7 yearsYou just
sed '$s/^/foo\n/'
to insert before the last one. -
terdon about 7 years@StéphaneChazelas yes, I know that now, after reading Kamaraj's answer, but I wasn't aware of that when I posted mine.
-
ACK_stoverflow about 2 yearsFor anyone who, like me, is trying to insert a leading tab with this solution and running into problems (perhaps because I'm using sed from busybox?) the following works:
sed -e '$i \' -e $'\t'"scan_ssid=1" /tmp/connect.conf