find a specific groupId from a maven pom.xml using xmstarlet - xmlstarlet

I'm trying to find a specific groupId and artifactId from a Maven POM.XML using xmlstarlet without success.
This is the command that I'm using:
xmlstarlet sel -N pom=http://maven.apache.org/POM/4.0.0 -t \
-m "/pom:project/pom:dependencyManagement/pom:dependencies/pom:dependency[.//pom:groupId=com.mygroup.xxx]" \
-v '.' pom.xml
any Help is appreciated.
EDIT: Thank to npostavs, for other people who have the same question, It is also possible to combine more expressions and filter the result based on more elements:
xmlstarlet sel -N pom=http://maven.apache.org/POM/4.0.0 -t -m "/pom:project/pom:dependencyManagement/pom:dependencies/dependency[.//pom:groupId='com.mygroup.xxx'][.//pom:artifactId='myartifact-xxx']" -v '.' pom.xml

pom:groupId=com.mygroup.xxx
You need quotes around string literals: pom:groupId='com.mygroup.xxx', otherwise it looks for XML elements named com.mygroup.xxx.

Related

How to print unix tool version in BusyBox container?

I can't figure out how to print (unix tool) versions within a BusyBox container:
$ docker run -it quay.io/quay/busybox:latest
$ awk --version
awk: unrecognized option `--version'
BusyBox v1.32.0 (2020-08-31 17:40:13 UTC) multi-call binary.
Usage: awk [OPTIONS] [AWK_PROGRAM] [FILE]...
-v VAR=VAL Set variable
-F SEP Use SEP as field separator
-f FILE Read program from FILE
-e AWK_PROGRAM
$ cut --version
cut: unrecognized option `--version'
BusyBox v1.32.0 (2020-08-31 17:40:13 UTC) multi-call binary.
Usage: cut [OPTIONS] [FILE]...
Print selected fields from each input FILE to stdout
-b LIST Output only bytes from LIST
-c LIST Output only characters from LIST
-d CHAR Use CHAR instead of tab as the field delimiter
-s Output only the lines containing delimiter
-f N Print only these fields
-n Ignored
Any suggestions? Many mulled containers are built on top of BusyBox, best I get on top of this.
Thanks
busybox is a single program which acts as one of various tools depending on what name was used to call it. As you can see in the question, it shows its version as BusyBox v1.32.0.
Check which tools are (symbolic) links to busybox. All these are the same program and therefore have the same version, so you might only need the version of busybox and a list of commands linked to it.
According to https://unix.stackexchange.com/q/15895/330217 the best way to display the version of busybox is
busybox | head -1

xmlstarlet add element with namespace and attributes

I'm trying to add a node with a namespace and an attribute to an xml, but it fails if I try to do it as multiple commands in one execution of xmlstarlet:
<?xml version="1.0"?>
<levela xmlns:xi="http://www.w3.org/2001/XInclude">
<levelb>
</levelb>
</levela>
xmlstarlet ed -L -s /levela/levelb -t elem -n xi:input -i //xi:input -t attr -n "href" -v "aHref" file.xml
I'm trying to get:
<?xml version="1.0"?>
<levela xmlns:xi="http://www.w3.org/2001/XInclude">
<levelb>
<xi:input href="aHref"/>
</levelb>
</levela>
But the attribute isn't added. So I get:
<?xml version="1.0"?>
<levela xmlns:xi="http://www.w3.org/2001/XInclude">
<levelb>
<xi:input/>
</levelb>
</levela>
It works if I run it as two executions like this:
xmlstarlet ed -L -s /levela/levelb -t elem -n xi:input file.xml
xmlstarlet ed -L -i //xi:input -t attr -n "href" -v "aHref" file.xml
It also works if I add a tag without a namespace e.g:
xmlstarlet ed -L -s /levela/levelb -t elem -n levelc -i //levelc -t attr -n "href" -v "aHref" file.xml
<?xml version="1.0"?>
<levela xmlns:xi="http://www.w3.org/2001/XInclude">
<levelb>
<levelc href="aHref"/>
</levelb>
</levela>
What am I doing wrong? Why doesn't it work with the namespace?
This will do it:
xmlstarlet edit \
-s '/levela/levelb' -t elem -n 'xi:input' \
-s '$prev' -t attr -n 'href' -v 'aHref' \
file.xml
xmlstarlet edit code can use the convenience $prev (aka
$xstar:prev) variable to refer to the node created by the most
recent -i (--insert), -a (--append), or -s (--subnode) option.
Examples of $prev are given in
doc/xmlstarlet.txt and
the source code's
examples/ed-backref*.
Attributes can be added using -i, -a, or -s.
What am I doing wrong? Why doesn't it work with the namespace?
Update 2022-04-15
The -i '//xi:input' … syntax you use is perfectly logical. As your
own 2 alternative commands suggest it's the namespace xi that
triggers the omission and there's a hint in the edInsert function in
the source code's
src/xml_edit.c
where it says NULL /* TODO: NS */.
When you've worked with xmlstarlet for some
time you come to accept its limitations (or not); in this case the
$prev back reference is useful. I wouldn't expect that TODO to
go away anytime soon.
(end update)
Well, I think xmlstarlet edit looks upon node naming as a user
responsibility, as the following example suggests,
printf '<v/>' |
xmlstarlet edit --omit-decl \
-s '*' -t elem -n 'undeclared:qname' -v 'x' \
-s '*' -t elem -n '!--' -v ' wotsinaname ' \
-s '$prev' -t attr -n ' "" ' -v '' \
-s '*' -t elem -n ' <&> ' -v 'harrumph!'
the output of which is clearly not XML:
<v>
<undeclared:qname>x</undeclared:qname>
<!-- "" =""> wotsinaname </!-->
< <&> >harrumph!</ <&> >
</v>
If you want to indent the new element, for example:
xmlstarlet edit \
-s '/levela/levelb' -t elem -n 'xi:input' \
--var newnd '$prev' \
-s '$prev' -t attr -n 'href' -v 'aHref' \
-a '$newnd' -t text -n ignored -v '' \
-u '$prev' -x '(//text())[1][normalize-space()=""]' \
file.xml
The -x XPath expression grabs the first text node provided it
contains nothing but whitespace, i.e. the first child node of levela.
The --var name xpath option to define an xmlstarlet edit
variable is mentioned in
doc/xmlstarlet.txt
but not in the user's guide.
I used xmlstarlet version 1.6.1.
It seems you can't insert an attribute and attribute value into a namespaced node... Maybe someone smarter can figure out something else, but the only way I could get around that, at least in this case, is this:
xmlstarlet ed -N xi="http://www.w3.org/2001/XInclude" --subnode "//levela/levelb" \
--type elem -n "xi:input" --insert "//levela/levelb/*" --type attr --name "href"\
--value "aHref" file.xml

Remove all files except some with constant name and some containing a special in unix

I want to remove all files in a directory except some in UNIX. Part I desired files have a known name and for the other part, I'm using ls|grep command. But the ls | grep is working when there is only one occurrence and not when there is more than one. it is the same with find|grep. here are my commands:
rm -v !("R1.r"|"R2.r"|"r2.par"|$(ls|grep nario)|"sh.sh")
rm -v !("R1.r"|"R2.r"|"r2.par"|$(find|grep nario)|"sh.sh")
Is there any problem with my commands???
It looks like you're trying to use BASH specific extglob syntax. ls|grep won't work in the middle of the glob, because each pattern needs to be separated by a |, which won't happen with ls|grep. The easier way to do what you want is to use the shell globbing to find the files under the directory you're looking for instead. Make sure you do the following:
Are using BASH
Have extglob enabled: shopt -s extglob
Have globstar enabled: shopt -s globstar
Use file globbing rather than ls | grep
Then try again:
rm -v !("R1.r"|"R2.r"|"r2.par"|**/*nario*|"sh.sh")
Note: globstar requires BASH version 4 or higher.

What field is a modding field mapped to after obfuscation?

For reflection purposes I need to know what the field name is after obfuscation, so I can do something like.
return ((Integer)ReflectionHelper
.getPrivateValue((Class)EntityLivingBase.class,
(Object)ent,
new String[] { "recentlyHit", "field_70718_bc" }))
.intValue();
How can I figure out this fieldname?
If you are under linux/mac, or on windows use the git bash shell
Open up a bash terminal
cd into your modding directory
Then issue the following command:
grep -rnw './' -e "age" | awk -F: '/RENAME MAP/ {print $4}'
And you'll get output like this:

Unix grep command

I have an utility script, that displays an information about deployed java app. Here is an example output of this script:
Name: TestAPP
Version : SNAPSHOT
Type : ear, ejb, webservices, web
Source path : /G/bin/app/TESTAPP_LIVE_1.1.9.1.1.ear
Status : enabled
Is it possible to grep Version and source path values using grep command? Right now im able to do this using following command:
| grep Version
But it outputs the whole string (e.g. Version: Snapshot) when i am need only a values (e.g Snapshot to use in further script commands)
grep Version | cut -d ':' -f 2
Here is a pure grep solution.
Use the -P option for regex mode, and -o option for retrieving only what is matching.
grep -Po "(?<=^Version : ).*"
Here is what you would do for Source:
grep -Po "(?<=^Source : ).*"
It uses a postive lookbehind.
Here's a solution using awk if you're interested:
grep Version | awk '{print $3}'
$3 means to print the third word from that line.
Note that:
This displays one word only
This assumes you have spaces between the colon (and therefore the version is actually the third "word"). If you don't, use $2 instead.

Resources