SED: append after first match - sed

Is there a way to append a text after first match only with sed? I've got something like this but text is inserted every second line:
sed -e '0,/priority/a\exclude = php*' /etc/yum.repos.d/epel.repo
File
$ cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
priority=3
[epel-debuginfo]
name=Extra Packages for Enterprise Linux 6 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1
priority=3
[epel-source]
name=Extra Packages for Enterprise Linux 6 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1
priority=3
UPDATE:
Desired output - exclude = php* should be only in the first repo ([epel]):
$ cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
priority=3
exclude = php*
...

You can say:
sed '/^priority/{s/.*/&\nexclude = php*/;:a;n;ba}' /etc/yum.repos.d/epel.repo

An awk solution in addition to sed
awk '/^priority/ && !f {$0=$0 RS "nexclude = php*";f=1}1' file
If search is found and f=0, then add text and set f=1. This prevents adding text after all priority.

sed '/priority/{x;/1/{x;b};s/^/1/;x;s/.*/&\nexclude = php*/}' file
the above line may work for you.

Related

Alpine Linux - sed - What Is The Equivalent Of -z or --null-data Switch When Using Alpine sed Utility?

In a previous project I used the sed utility to replace newlines with NUL characters for compatibility with the API for adding a release note on the CI server.
sed -zE 's/\r\n|\n/\\n/g' < CHANGELOG.md
However, in a different project I am using an alpine based docker image (mcr.microsoft.com/dotnet/core/sdk:3.1-alpine) and the -z or --null-data image is unrecognised on alpine linux when using the sed utility.
How do I achieve the equivalent of the -z or --null-data with Alpine Linux sed utility?
What Is The Equivalent Of -z or --null-data Switch When Using Alpine sed Utility?
There is no equivalent.
How do I achieve the equivalent of the -z or --null-data with Alpine Linux sed utility?
Instead of using busybox sed, install GNU sed.
/ # sed --help
BusyBox v1.31.1 () multi-call binary.
/ # apk add sed
...
/ # sed --version
sed (GNU sed) 4.8
I used the sed utility to replace newlines with NUL
Use tr, it's a tool created to "translate or delete characters".
tr '\n' '\0'
sed -zE 's/\r\n|\n/\\n/g'
If you want to remote \r, no need to use zero separated streams. Just remove \r character from the actual end of line, why match the newline, if sed already works on lines.
sed 's/\r$//'
but really, again, to remove characters use tr:
tr -d '\r'

Apache Kafka 2.12-1.1.0 not working with JDK -10.0.1

Why doesn't Apache Kafka 2.12-1.1.0 work with JDK 10.0.1?
./bin/zookeeper-server-start.sh config/zookeeper.properties
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)
/..../kafka_2.12-1.1.0/bin/kafka-run-class.sh: line 252: [[: 10 2018-04-17: syntax error in expression (error token is "2018-04-17")
[0.000s][warning][gc] -Xloggc is deprecated. Will use -Xlog:gc:/..../kafka_2.12-1.1.0/bin/../logs/zookeeper-gc.log instead.
Unrecognized VM option 'PrintGCDateStamps'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Changing the bin/kafka-run-class.sh with below code did the magic:
In Line #251
Before:
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([^.-]*).*"/\1/p')
After:
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([^.-]*).*/\1/p')
You can remove the offending logging option KAFKA_GC_LOG_OPTS for java 10 from the file kafka-run-class.sh
from
KAFKA_GC_LOG_OPTS="-Xloggc:$LOG_DIR/$GC_LOG_FILE_NAME -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
to
KAFKA_GC_LOG_OPTS="-Xloggc:$LOG_DIR/$GC_LOG_FILE_NAME -verbose:gc -XX:+PrintGCDetails"
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version
"([0-9]).$/\1/p')
This line solved my problem with openjdk!
This is the original line from bin/kafka-run-class.sh that you need replace:
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version
"([^.-])."/\1/p')
There is a problem in the regex used for identifying the java version in the bin/kafka-run-class.sh especially if you are using openjdk.
You can replace line 255 in the bin/kafka-run-class.sh with :
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([0-9]*).*$/\1/p')
as in https://github.com/apache/kafka/blob/trunk/bin/kafka-run-class.sh#L286
Above all answers are from the shell script point of view. If some people are using a bat file on the windows machine below answer will be helpful.
Windows Bat file
Go to ..\kafka_2.12-2.2.0\bin\windows and search for kafka-run-class.bat file
Go to Line Number 158 and set the JDK Path.
IF ["%JAVA_HOME%"] EQU [""] (
set JAVA=java
) ELSE (
set JAVA="..\Java\jdk12\bin\java"
)
Shell Script
Go to ..\kafka_2.12-2.2.0\bin\ and search for kafka-run-class.sh file.
and then search for $JAVA_HOME and go this line update your JDK path accordingly.
if [ -z "$JAVA_HOME" ]; then
JAVA="java"
else
JAVA="$JAVA_HOME\java"
fi
JAVA = "../Java/jdk12/bin/java"
echo $JAVA
I think this will address the issue. This will occur when we have multiple JDK installed on our machine and want to test the things.
I removed the tags like PrintGCDateStamps,UseGCLogFileRotation from line 314

sed code works in 4.2.1 but not 4.1.5

I have the following sed code that works in RH6 and sed 4.2.1
>> echo "SUSE Linux Enterprise Server 11 ( x86_64 ) VERSION = 11 PATCHLEVEL = 2" | sed s/.*VERSION\ =\ //
11 PATCHLEVEL = 2
>> sed --version
GNU sed version 4.2.1
but it fails at SUSE 11 and sed 4.1.5
>> echo "SUSE Linux Enterprise Server 11 ( x86_64 ) VERSION = 11 PATCHLEVEL = 2" | sed s/.*VERSION\ =\ //
sed: No match.
>> sed --version
GNU sed version 4.1.5
I found the following code works differently in the two versions. sed 4.1.5 in SUSE cannot match anything.
echo ab | sed s/.*//
Is it a known issue of sed? and does it have a solution?
Since you didn't quote the asterisk, your shell is trying to glob it. On one of your systems this globbing fails and the original string is returned. On your other system it matches something and your substitution regex is destroyed. Always quote arguments that the shell might consider "special".
I found sed 4.1.5 needs single quotes to make things work. The following works.
echo ab | sed 's/.*//'
But the sed 4.2.1 does not need this.

Why won't a module installed by `cpanm` be recognized?

I installed perl-5.12.2 using perlbrew:
perlbrew install perl-5.12.2 -D=usethreads -D=useithreads -D=uselargefiles -f
I then switched to this version and installed IPC::System::Simple using cpanm.
However, when I try to run my script I get:
Can't locate IPC/System/Simple.pm in #INC (#INC contains: /home/dave/workspace/proj1/scripts/bin/../lib /home/dave/src/bioperl-live /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2/x86_64-linux-thread-multi /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2 /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2/x86_64-linux-thread-multi /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2 .) at /home/dave/workspace/proj1/scripts/bin/../lib/createLayout.pm line 14.
I also found the following dir:
~/perl5/lib/perl5/x86_64-linux-thread-multi/auto/IPC/System/Simple
but it's empty (I have no idea if this means something).
Try this step-by-step guide, paying close attention to steps 7 and 8 (and optionally 9).
What does which cpanm from the command line show? For you it should report:
/home/dave/perl5/perlbrew/bin/cpanm
If thats OK then what does ls -l /home/dave/perl5/perlbrew/bin/cpanm show? It should be pointing to:
cpanm -> /home/dave/perl5/perlbrew/perls/current/bin/cpanm
And finally ls -l /Users/barry/perl5/perlbrew/perls/current should be pointing to the Perl you've switched to in perlbrew:
/home/dave/perl5/perlbrew/perls/current -> perl-5.12.2
All three of these must be like this otherwise something is wrong.
If its not then one likely issue is that cpanm is pointing to another installed Perl. You need to have cpanm installed for each version of perl under perlbrew:
perlbrew switch perl-5.12.2
curl -L http://cpanmin.us | perl - App::cpanminus
Now if which cpanm still doesn't show the perlbrew path then you have a $PATH precedence issue in your .bash_profile (or equivalent) file. This can be fixed by making sure that your perlbrew line...
source /home/dave/perl5/perlbrew/etc/bashrc
... in the profile file is after any other export $PATH lines.
After re-login back in you can confirm that this is right by doing echo $PATH and you should see perlbrew at the beginning (the left) of the path string, ie. something like this:
/home/dave/perl5/perlbrew/bin:/home/dave/perl5/perlbrew/perls/current/bin:/usr/bin:/bin:/usr/local/bin:

sed on sun solaris

I am try to do the following on sun solaris
sed "/ADDRESS/a \
PROTOCOL" file > NEW_file
but I get:
sed: command garbled: /ADDRESS/a PROTOCOL
why (on linux its work) ,
is it possible to support syntax that work on linux and on sun
lidia
here's another way, use nawk
nawk '/ADDRESS/{$0=$0" PROTOCOL"}1' file
This syntax is a Gnu sed extension. It works on Gnu/Linux because you have a Gnu userland with it. It works on Solaris if Gnu sed is installed on it. It might be in /usr/gnu/bin/sed, /usr/sfw/bin/gsed or somewhere else, depending on the Solaris release you are using.