Я попытался создать скрипт, который экономит мое время. Это то, что я хочу сделать: у меня есть один большой XML-файл с разделами, скажем, он выглядит так:
some text
.....
HEAD
context A
TAIL
some text
.....
HEAD
context B
TAIL
....
some text
....
HEAD
context C
TAIL
....
some text
Мне нужно вырезать секцию с помощью context A и перейти к контексту файлаA, затем context B в файл contextB и т. д. (Все файлы должны содержать синтаксис HEAD context x TAIL). Проблема в том, что все контексты начинаются и заканчиваются в одном и том же регулярном выражении (HEAD и TAIL).
Можете ли вы мне помочь?
Это небольшое обновление, потому что, может быть, я недостаточно прояснил его: пусть скажет мой файл выглядит так:
some text 1
<config>
1
2
3
</config>
some text 2
<config>
4
5
6
</config>
some text 3
<config>
7
8
9
</config>
some text 4
, и я хочу, чтобы файл с именем:
«первым», который содержит:
<config>
1
2
3
</config>
«second», которые содержат: [ ! d6] <config>
4
5
6
</config>
и т. д.
Это проще сделать с awk:
awk -v RS="HEAD\n" -v FS="\n" 'NR>1{print "HEAD\n" $0 > $1".txt"}' ex
Примечания: регистры
RS="HEAD\n" разделены «HEAD \ n» FS="\n", каждое поле является line NR>1{print "HEAD\n" $0 > $1} для всех регистров, кроме первого, напишите его в файл с именем field 1 - «$ 1»UPDATE: для нового вопроса:
awk -v RS="<config>\n" -F"</config>" 'NR>1{print RS $1 FS > "conf-"NR-1}' ex
Конфигурация выходы хранятся в файлах с именем «conf-1»
Это проще сделать с awk:
awk -v RS="HEAD\n" -v FS="\n" 'NR>1{print "HEAD\n" $0 > $1".txt"}' ex
Примечания: регистры
RS="HEAD\n" разделены «HEAD \ n» FS="\n", каждое поле является line NR>1{print "HEAD\n" $0 > $1} для всех регистров, кроме первого, напишите его в файл с именем field 1 - «$ 1»UPDATE: для нового вопроса:
awk -v RS="<config>\n" -F"</config>" 'NR>1{print RS $1 FS > "conf-"NR-1}' ex
Конфигурация выходы хранятся в файлах с именем «conf-1»
Это проще сделать с awk:
awk -v RS="HEAD\n" -v FS="\n" 'NR>1{print "HEAD\n" $0 > $1".txt"}' ex
Примечания: регистры
RS="HEAD\n" разделены «HEAD \ n» FS="\n", каждое поле является line NR>1{print "HEAD\n" $0 > $1} для всех регистров, кроме первого, напишите его в файл с именем field 1 - «$ 1»UPDATE: для нового вопроса:
awk -v RS="<config>\n" -F"</config>" 'NR>1{print RS $1 FS > "conf-"NR-1}' ex
Конфигурация выходы хранятся в файлах с именем «conf-1»
Мой скрипт с использованием awk:
#!/bin/bash
for i in $(seq -w $(<"$1" grep -cx "$2")); do
<"$1" >$i awk -va=$i -vb="$2" -vc="$3" '$0~b{d++;e=1}d==a&&e==1;$0~c{e=0}'
done
Сохраните его, например. myscript.sh, сделайте его выполнимым, перейдите к своему onebig.xml и вызовите его следующим образом:
/path/to/myscript.sh onebig.xml HEAD TAIL
Он вырезает каждую секцию из onebig.xml, начиная с HEAD и заканчивая на TAIL и сохраните их как 1, 2, ... если в разделе 01, 02, ... есть 10 секций, ... если есть 10 - 99 разделов, то как 001, 002, ... если есть от 100 до 999 секций и т. д.
Если вы действительно не можете использовать для этого правильный XML-анализатор, я бы предложил awk, например
awk '/^HEAD/ {p=1; ++n} p {print > "context"n} /^TAIL/ {p=0}' file.xml
выведет секции HEAD ... TAIL в числовые имена файлов context1, context2 и т. д.
Для упрощения сортировки вы можете немного улучшить его, построив числовой префикс фиксированной ширины, например
$ awk '/^HEAD/ {p=1; outfile = sprintf("context%03d", ++n)} p {print > outfile} /^TAIL/ {p=0}' file.xml
$ head context*
==> context001 <==
HEAD
context A
TAIL
==> context002 <==
HEAD
context B
TAIL
==> context003 <==
HEAD
context C
TAIL
Пожалуйста, проверьте, помогает ли ниже скрипт:
#!/bin/bash
for x in {A..Z}; do
# check if the pattern exists in the file
if grep -qF "context $x" file.txt; then
# Store the lines between the 2 patterns including the matching lines in a text file
awk '/context '$x'/,/TAIL/' file.txt > context$x.txt
else
echo "Sorry this pattern does not exists in file"
fi
done
Мой скрипт с использованием awk:
#!/bin/bash
for i in $(seq -w $(<"$1" grep -cx "$2")); do
<"$1" >$i awk -va=$i -vb="$2" -vc="$3" '$0~b{d++;e=1}d==a&&e==1;$0~c{e=0}'
done
Сохраните его, например. myscript.sh, сделайте его выполнимым, перейдите к своему onebig.xml и вызовите его следующим образом:
/path/to/myscript.sh onebig.xml HEAD TAIL
Он вырезает каждую секцию из onebig.xml, начиная с HEAD и заканчивая на TAIL и сохраните их как 1, 2, ... если в разделе 01, 02, ... есть 10 секций, ... если есть 10 - 99 разделов, то как 001, 002, ... если есть от 100 до 999 секций и т. д.
Если вы действительно не можете использовать для этого правильный XML-анализатор, я бы предложил awk, например
awk '/^HEAD/ {p=1; ++n} p {print > "context"n} /^TAIL/ {p=0}' file.xml
выведет секции HEAD ... TAIL в числовые имена файлов context1, context2 и т. д.
Для упрощения сортировки вы можете немного улучшить его, построив числовой префикс фиксированной ширины, например
$ awk '/^HEAD/ {p=1; outfile = sprintf("context%03d", ++n)} p {print > outfile} /^TAIL/ {p=0}' file.xml
$ head context*
==> context001 <==
HEAD
context A
TAIL
==> context002 <==
HEAD
context B
TAIL
==> context003 <==
HEAD
context C
TAIL
Пожалуйста, проверьте, помогает ли ниже скрипт:
#!/bin/bash
for x in {A..Z}; do
# check if the pattern exists in the file
if grep -qF "context $x" file.txt; then
# Store the lines between the 2 patterns including the matching lines in a text file
awk '/context '$x'/,/TAIL/' file.txt > context$x.txt
else
echo "Sorry this pattern does not exists in file"
fi
done
Мой скрипт с использованием awk:
#!/bin/bash
for i in $(seq -w $(<"$1" grep -cx "$2")); do
<"$1" >$i awk -va=$i -vb="$2" -vc="$3" '$0~b{d++;e=1}d==a&&e==1;$0~c{e=0}'
done
Сохраните его, например. myscript.sh, сделайте его выполнимым, перейдите к своему onebig.xml и вызовите его следующим образом:
/path/to/myscript.sh onebig.xml HEAD TAIL
Он вырезает каждую секцию из onebig.xml, начиная с HEAD и заканчивая на TAIL и сохраните их как 1, 2, ... если в разделе 01, 02, ... есть 10 секций, ... если есть 10 - 99 разделов, то как 001, 002, ... если есть от 100 до 999 секций и т. д.
Если вы действительно не можете использовать для этого правильный XML-анализатор, я бы предложил awk, например
awk '/^HEAD/ {p=1; ++n} p {print > "context"n} /^TAIL/ {p=0}' file.xml
выведет секции HEAD ... TAIL в числовые имена файлов context1, context2 и т. д.
Для упрощения сортировки вы можете немного улучшить его, построив числовой префикс фиксированной ширины, например
$ awk '/^HEAD/ {p=1; outfile = sprintf("context%03d", ++n)} p {print > outfile} /^TAIL/ {p=0}' file.xml
$ head context*
==> context001 <==
HEAD
context A
TAIL
==> context002 <==
HEAD
context B
TAIL
==> context003 <==
HEAD
context C
TAIL
Пожалуйста, проверьте, помогает ли ниже скрипт:
#!/bin/bash
for x in {A..Z}; do
# check if the pattern exists in the file
if grep -qF "context $x" file.txt; then
# Store the lines between the 2 patterns including the matching lines in a text file
awk '/context '$x'/,/TAIL/' file.txt > context$x.txt
else
echo "Sorry this pattern does not exists in file"
fi
done