POSIXly:
after_first_where=${opts#*-where }
word_after_where=${after_first_where%% *}
Или разрешить любое количество пробелов между словами:
after_first_where=${opts#*-where}
word_after_where=${after_first_where#"${after_first_where%%[![:blank:]]*}"}
word_after_where=${word_after_where%%[[:blank:]]*}
Или вы можете сделать:
unset -v IFS; set -f # split on blanks, no glob
set -- $opts # splits $opts into $1, $2, $3...
while [ "$#" -ge 2 ]; do
case $1 in
(-age|-name|-where|-eats)
eval "${1#-}=\$2" # assigns name=$2 or where=$2...
shift 2;;
(*) shift
esac
done
printf '%s\n' "$name eats $eats in $where"
Обратите внимание, что в этом случае пробелы ограничиваются космосом, табуляцией (и новой строкой), а не другими символами, которые могут рассматриваться как [: пустое:]
в вашем языке.
Для Debian :
На моем ПК
~ > dpkg --print-architecture amd64
~ > dpkg --print-foreign-architectures i386
My Малины Pi 2
~ > dpkg --print-architecture armhf-121--3671-
Для правильного ответа на этот вопрос нам в идеале нужен лучший пример - некоторые действительные xml - это хорошее начало.
Также - пример требуемого выхода. Например, вы не указываете, где элементы < C >
и < D >
должны оказаться в результирующем XML. Они уже потомки < B >
- сохранить B
или репаратировать C
и D
в корень?
Однако общая реконструкция XML
довольно проста с помощью XML:: Twig
и perl
.
Например. Как и так:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my @wanted = qw ( C D id );
my %wanted = map { $_ => 1 } @wanted;
sub delete_unwanted_tags {
my ( $twig, $element ) = @_;
my $tag = $element -> tag;
if ( not $wanted{$tag} ) {
$element -> delete;
}
}
my $twig = XML::Twig -> new ( twig_handlers => { _all_ => \&delete_unwanted_tags } );
$twig -> parse ( \*DATA );
$twig -> print;
__DATA__
<A>
<id>123</id>
<B>
<C>value1</C>
<D>value2</D>
<E></E>
</B>
<Z></Z>
<Y></Y>
</A>
Потому что мы не сказали «keep < B >
» результат:
<A>
<id>123</id>
</A>
Добавление < B >
в список желаемых
:
<A>
<id>123</id>
<B>
<C>value1</C>
<D>value2</D>
</B>
</A>
Если, однако, вы хотите выполнить репарацию C
и D
в A
:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my @wanted = qw ( id);
my @reparent = qw ( C D );
#turn the above into hashes, so we can do "if $wanted{$tag}"
my %wanted = map { $_ => 1 } @wanted;
my %reparent = map { $_ => 1 } @reparent;
sub delete_unwanted_tags {
my ( $twig, $element ) = @_;
my $tag = $element->tag;
if ( not $wanted{$tag} ) {
$element->delete;
}
if ( $reparent{$tag} ) {
$element->move( 'last_child', $twig->root );
}
}
my $twig = XML::Twig->new(
pretty_print => 'indented_a',
twig_handlers => { _all_ => \&delete_unwanted_tags }
);
$twig->parse( \*DATA );
$twig->print;
__DATA__
<A>
<id>123</id>
<B>
<C>value1</C>
<D>value2</D>
<E></E>
</B>
<Z></Z>
<Y></Y>
</A>
Примечание - «обработчик ветвей» вызывается на конце каждого элемента (когда встречается близкий тэг), поэтому это работает - мы рекурсируем вниз, чтобы найти C
и D
, прежде чем закончить обработку (и удаление) B
.
Это приводит к:
<A>
<id>123</id>
<C>value1</C>
<D>value2</D>
</A>
В вышеизложенном я использовал __ DATA __
, \* DATA
и синтаксический анализ
, поскольку он позволяет мне проиллюстрировать как XML, так и технологии. Вместо синтаксического анализа (\* DATA)
следует использовать parsefile ('my _ file.xml')
.