Using Raku (formerly known as Perl_6)
~$ raku -MXML -e 'my $xml = open-xml( $*ARGFILES.Str ); for $xml.elements( :RECURSE(0), :TAG{"file"} ) -> $E { my $old = $E.contents[0]; my $new = XML::Text.new( text => $old.text.match(/ <?after "/"> <-[/]>+ $/) ); $E.replace( $old, $new ); }; .say for $xml;' file.xml
OR:
% raku -MXML -e 'my $xml = open-xml( $*ARGFILES.Str ); for $xml.elements( :RECURSE(0), :TAG{"file"} ) -> $E { my $old = $E.contents[0]; my $new = XML::Text.new( text => $old.text.path.basename ); $E.replace( $old, $new ); }; .say for $xml;' file.xml
Raku is a programming language in the Perl-family that features high-level Grammars for parsing text. Along with Raku/Rakudo itself, community members support modules in the Raku/Rakudo ecosystem. One of those modules is the (Raku-native) XML
module.
Similar to the OP's other question, in Raku with the XML
-module you can (for example) limit replacements to 1). the top-level and 2). within only the <file>
TAG. This is done by setting the code to iterate through elements
with the limitations :RECURSE(0), :TAG{"file"}
. FYI, you can iterate through all TAG
s at all depths if so desired: simply set :RECURSE(Inf)
and remove the :TAG
named-argument, which sets the :TAG
restriction to False.
The first answer above identifies suitable TAGs/levels for replacement. Thus identified, each element's internal (i.e. non-TAG) contents[0]
are assigned to the variable $old
, which is actually an XML::Text
object. The $old
object is .text
extracted into a string, and the desired match
is found. A new (XML::Text.new
) object is created ($new
) with the now-corrected text => 'value'
key/value pair. From here the XML
-module's replace
routine completes the job: replace( $old, $new )
.
The second answer above is a clever twist on the first. Because the OP wants to edit path names, routines associated with Raku's IO::Path
object class can be used. Raku's .IO
routine understands the text as a valid path name, and Raku's .basename
routine returns the final filename. This approach has the potential to increase code portability, because Raku has mechanisms for using the correct (/
or \
) path-separator on different platforms.
Sample Input (thanks to @GillesQuénot!):
<r> <file>Documents/time/text1</file> <file>Commun/text2</file> <file>Current/text3</file> </r>
Sample Output:
<?xml version="1.0"?><r> <file>text1</file> <file>text2</file> <file>text3</file> </r>
https://github.com/raku-community-modules/XML
https://docs.raku.org/type/IO/Path
https://rakudo.org/
https://raku.org
does not work
... (syntax) error? wrong output? hangs?sed -i
" then edit your question to clarify what you mean by "in line" and what exactly the problem is you're trying to solve.