LINUX.ORG.RU

История изменений

Исправление vodz, (текущая версия) :

А можно какое-то пример.

Таки заставили подняпрячься.

Запускать xml-cut.sh < in.xml > out.xml

Вырезает из in.xml <tag [attrs]>.*</tag> первого уровня (тег без учёта регистра), то есть оставляя то, что внутри .*, вложенные эти теги остаются тоже. Теги могут быть в виде несколько блоков первого уровня, на выходе только первый блок. Всякие пробелы там и сям — допускаются.

#!/usr/bin/env bash

TAG=tag
TAGC='[Tt][Aa][Gg]'

IFS= read -r -d '' b

r=$'(\r+)(.*)'
while [[ $b =~ $r ]]; do
	b=${b:0:${#b}-${#BASH_REMATCH[0]}}${BASH_REMATCH[2]}
done

a=
r=$'<[ \t\n]*'$TAGC$'([ \t\n]+([^>]*))?>[ \t\n]*(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG ${BASH_REMATCH[2]}>"
	b=${BASH_REMATCH[3]}
done
b=$a$b

a=
r=$'[ \t\n]*</[ \t\n]*'$TAGC$'[ \t\n]*>(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}</$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

r="<$TAG [^>]*>(.*)</$TAG>"
if [[ $b =~ $r ]]; then
	b=${BASH_REMATCH[1]}
else
	echo "<$TAG [attrs]>.*</$TAG> не найдено" >&2
	exit 1
fi

while true; do
	 r="(.*)<$TAG "
	 if [[ $b =~ $r ]]; then
		 p=${BASH_REMATCH[1]}
		 a=${b:${#BASH_REMATCH[0]}}
		 b=$a
		 r="</$TAG>"
		 if [[ ! $b =~ $r ]]; then
			 b=$p
			 r="(.*)</$TAG>"
			 if [[ $b =~ $r ]]; then
				 b=${BASH_REMATCH[1]}
				 continue
			 fi
			 echo "(<$TAG [attrs]>.*</$TAG>)+ несбалансировано" >&2
			 exit 1
		 fi
		 b="$p<$TAG $a"
	 fi
	 break
done

a=
r="<$TAG >(.*)"
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

printf "%s" "$b"

Коментарии к этому за отдельный интересный вопрос.

Исправление vodz, :

А можно какое-то пример.

Таки заставили подняпрячься.

Запускать xml-cut.sh < in.xml > out.xml

Вырезает из in.xml <tag [attrs]>.*</tag> первого уровня (тег без учёта регистра), то есть оставляя то, что внутри .*, вложенные эти теги остаются тоже. Теги могут быть в виде несколько блоков первого уровня, на выходе только первый блок.

#!/usr/bin/env bash

TAG=tag
TAGC='[Tt][Aa][Gg]'

IFS= read -r -d '' b

r=$'(\r+)(.*)'
while [[ $b =~ $r ]]; do
	b=${b:0:${#b}-${#BASH_REMATCH[0]}}${BASH_REMATCH[2]}
done

a=
r=$'<[ \t\n]*'$TAGC$'([ \t\n]+([^>]*))?>[ \t\n]*(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG ${BASH_REMATCH[2]}>"
	b=${BASH_REMATCH[3]}
done
b=$a$b

a=
r=$'[ \t\n]*</[ \t\n]*'$TAGC$'[ \t\n]*>(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}</$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

r="<$TAG [^>]*>(.*)</$TAG>"
if [[ $b =~ $r ]]; then
	b=${BASH_REMATCH[1]}
else
	echo "<$TAG [attrs]>.*</$TAG> не найдено" >&2
	exit 1
fi

while true; do
	 r="(.*)<$TAG "
	 if [[ $b =~ $r ]]; then
		 p=${BASH_REMATCH[1]}
		 a=${b:${#BASH_REMATCH[0]}}
		 b=$a
		 r="</$TAG>"
		 if [[ ! $b =~ $r ]]; then
			 b=$p
			 r="(.*)</$TAG>"
			 if [[ $b =~ $r ]]; then
				 b=${BASH_REMATCH[1]}
				 continue
			 fi
			 echo "(<$TAG [attrs]>.*</$TAG>)+ несбалансировано" >&2
			 exit 1
		 fi
		 b="$p<$TAG $a"
	 fi
	 break
done

a=
r="<$TAG >(.*)"
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

printf "%s" "$b"

Коментарии к этому за отдельный интересный вопрос.

Исходная версия vodz, :

А можно какое-то пример.

Таки заставили подняпрячься.

Запускать xml-cut.sh < in.xml > out.xml

Вырезает из in.xml <tag [attrs]>.*</tar> первого уровня, то есть оставляя то что внутри .*, оставляя вложенные эти теги. Теги могут быть несколько блоков первого уровня, на выходе только первый блок.

#!/usr/bin/env bash

TAG=tag
TAGC='[Tt][Aa][Gg]'

IFS= read -r -d '' b

r=$'(\r+)(.*)'
while [[ $b =~ $r ]]; do
	b=${b:0:${#b}-${#BASH_REMATCH[0]}}${BASH_REMATCH[2]}
done

a=
r=$'<[ \t\n]*'$TAGC$'([ \t\n]+([^>]*))?>[ \t\n]*(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG ${BASH_REMATCH[2]}>"
	b=${BASH_REMATCH[3]}
done
b=$a$b

a=
r=$'[ \t\n]*</[ \t\n]*'$TAGC$'[ \t\n]*>(.*)'
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}</$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

r="<$TAG [^>]*>(.*)</$TAG>"
if [[ $b =~ $r ]]; then
	b=${BASH_REMATCH[1]}
else
	echo "<$TAG [attrs]>.*</$TAG> не найдено" >&2
	exit 1
fi

while true; do
	 r="(.*)<$TAG "
	 if [[ $b =~ $r ]]; then
		 p=${BASH_REMATCH[1]}
		 a=${b:${#BASH_REMATCH[0]}}
		 b=$a
		 r="</$TAG>"
		 if [[ ! $b =~ $r ]]; then
			 b=$p
			 r="(.*)</$TAG>"
			 if [[ $b =~ $r ]]; then
				 b=${BASH_REMATCH[1]}
				 continue
			 fi
			 echo "(<$TAG [attrs]>.*</$TAG>)+ несбалансировано" >&2
			 exit 1
		 fi
		 b="$p<$TAG $a"
	 fi
	 break
done

a=
r="<$TAG >(.*)"
while [[ $b =~ $r ]]; do
	a+="${b:0:${#b}-${#BASH_REMATCH[0]}}<$TAG>"
	b=${BASH_REMATCH[1]}
done
b=$a$b

printf "%s" "$b"

Коментарии к этому за отдельный интересный вопрос.