Reputation: 5346
I have a property file for java like below.
server.port=8080
spring.application.name=app1
spring.datasource.driver-class-name=org.mysql.jdbc.Driver
I want to convert the file to a linux equivalent property file like below.
SERVER_PORT=8080
SPRING_APPLICATION_NAME=app1
SPRING_DATASOURCE_DRIVER_CLASS_NAME=org.mysql.jdbc.Driver
I am using sed
, and I am able to convert the property names with the following sed command.
sed "s/^\(.*\)=\(.*\)$/\U\1=\E\2/" application.properties
However, I am not able to figure out how to replace the dots(.
) with underscore(_
) character in the matched part(\1
).
Can somebody help?
Upvotes: 1
Views: 178
Reputation: 437783
An alternative perl
solution that is perhaps conceptually simpler: Tip of the hat to @Sundeep for his help with simplifying the command.
perl -F'(=)' -ane '$F[0] = uc $F[0] =~ tr/./_/r; print @F' application.properties
-F(=)
, combined with -a
, splits each input line into fields by =
. (-n
suppresses default output, and -e
tells Perl to treat the next operand as a command).
Enclosing =
in (...)
also makes the =
instances part of the field array stored in @F
.
$F[0] =~ tr/./_/r
translates all literal .
chars. into _
chars. in the 1st field (the property name) and returns the result, thanks to the r
option.
$F[0] = uc
then converts the result to all-uppercase and updates the 1st field with the result.
print @F
then prints all fields, starting with the modified 1st field, separated by =
(the output field separators that were also captured in @F
), in effect printing the upper-cased 1st input field with .
chars. translated to _
, followed by =
and the unmodified remainder of the input line.
Upvotes: 2
Reputation: 23667
If perl
is okay:
$ perl -pe 's/^.*=/\U$&/; s/^.*=/$&=~s|\.|_|gr/e' application.properties
SERVER_PORT=8080
SPRING_APPLICATION_NAME=app1
SPRING_DATASOURCE_DRIVER-CLASS-NAME=org.mysql.jdbc.Driver
s/^.*=/$&=~s|\.|_|gr/e
use another substitution for captured text ^.*=
Can be simplified to
$ perl -pe 's/^.*=/uc $&=~s|\.|_|gr/e' application.properties
SERVER_PORT=8080
SPRING_APPLICATION_NAME=app1
SPRING_DATASOURCE_DRIVER-CLASS-NAME=org.mysql.jdbc.Driver
With sed
$ sed 's/^.*=/\U&/; :a s/^\([^=]*\)\./\1_/g; ta' application.properties
SERVER_PORT=8080
SPRING_APPLICATION_NAME=app1
SPRING_DATASOURCE_DRIVER-CLASS-NAME=org.mysql.jdbc.Driver
:a s/^\([^=]*\)\./\1_/g; ta
replace .
with _
until the text before .
doesn't contain =
If both .
and -
before =
needs to be changed to _
, use [.-]
instead of \.
in both solutions
Upvotes: 2
Reputation: 52132
With cut
, tr
, paste
and process substitution (requires Bash):
$ paste -d= <(cut -f1 -d= application.properties | tr '[:lower:].-' '[:upper:]_') \
> <(cut -f2 -d= application.properties)
SERVER_PORT=8080
SPRING_APPLICATION_NAME=app1
SPRING_DATASOURCE_DRIVER_CLASS_NAME=org.mysql.jdbc.Driver
Both cut
and paste
use =
as the delimiter, and the first cut
pipes to tr
for uppercasing and replacing periods and dashes with underscores.
Upvotes: 2
Reputation: 89557
You can use a conditional loop:
sed 's/^[^=]*/\U&/;:a;s/^\([^=]*\)[.-]/\1_/;ta'
Where ta
jumps to the label "a" as long as something is replaced.
With awk:
awk -F= -vOFS='=' '{$1=toupper($1);gsub("[-.]", "_", $1)}1'
Upvotes: 2