Да, спасибо @George Vasiliou, я смог заставить это работать, теперь сценарий работает так:
#!/bin/sh
echo "file to split?"
read file
# This variable is to name resulting files
f=0
while :
do
# Count how many occurrences of "<text" are in the file to split
count=$(grep "<text" "$file" | wc -l)
if [ "$count" -gt 1 ]
then
# Send the occurrences of "<text" with their line number to the titles.txt file
grep -n "<text" "$file" > titles.txt
# From the second line of titles get the line number
lines=$(cat titles.txt| sed -n 2'p' | sed -r 's/^([0-9]*).*/\1/g')
# Every time the script is run the resulting file gets the next number as name
f=$((f+1))
# From the line number obtained at the second line substract 1
substrac="$(($lines-1))"
# Create a new file taking the amount of lines indicated by the substraction from the splitting file
head -"$substrac" "$file" > "$f"
# Delete the lines corresponding to the newly created file from the splitting file to start the process over
sed -i '1,'"$substrac"'d' "$file"
echo "file \"$f\" generated"
else
echo "process finished!"
exit 1;
fi
done
Пояснение:У меня есть огромный текстовый файл такого формата:
<text id="cade2296-1">
many
undetermined
lines
...
</text>
The same schema repeteated undetermined times
<text id="cafr3062-1">
many
undetermined
lines
...
</text>
А мне нужна каждая схема в отдельном файле.
Вы успешно нашли одну из вещей, которые вам не следует делать :-)Никогда не перенаправляйте на файл, над которым вы работаете!
A1 :хорошим ресурсом для изучения грамматики оболочки будет абсолютное руководство по написанию сценариев bash , IMO
A2 :Для скриптов bash -вы можете использовать set +x
для получения более подробного вывода, но я не знаю, как добиться того же на уровне «запускать вещи в подсказке» -.
A3 :Добавьте [solved]
к условиям поиска -. Находит вам решение вашей проблемы, а не больше проблемы, которую вы уже знаете.
Рассмотрите 3.1.1 Операцию оболочки , особенно порядок, в котором выполняются действия:
Это означает, что для cat file > file
перенаправление вывода (, усекающее файл ), происходит до создания cat
, а cat
теперь имеет пустой файл для работы.
Но echo "$(cat file)" > file
делает то, что вы ожидаете, потому что Подстановка команд является Расширением оболочки , и это происходит до перенаправления.
Типичный совет — делать
cat file > tmpfile && mv tmpfile file
Здесь вы можете использовать mktemp
.
Или установите пакет moreutils
и используйтеsponge
cat file | sponge file
Хотя для решения конкретной используемой команды замените
cat file.txt | sed 's/a/1/' > file.txt
с (в предположении GNU sed)
sed -i 's/a/1/' file.txt
Одним из способов решения проблемы является точное изучение того, в каком порядке происходят перенаправления, расширения, подоболочки и т. д., чтобы вы могли обнаруживать ошибки такого типа до того, как они произойдут.
Я не рекомендую это делать. Вы все равно будете время от времени ошибаться, и стоимость может быть потеряна.
Лучше не доверять своей способности сохранить все это прямо и написать больше идиотского -кода подтверждения. Все мы иногда бываем идиотами.
Так
cp file.txt file.txt.old
cat file.txt.old | sed 's/a/1/' > file.txt
Это проще, поскольку нет зависимости от порядка событий, за исключением того, что строка 1 происходит перед строкой 2.
В качестве дополнительного преимущества он защищает от других ошибок, когда вообще не следовало запускать этот скрипт.
Цена этой практики заключается в том, что у вас будут .old
файлы, лежащие повсюду. Это страховая премия, вы будете рады, что заплатили в тот день, когда она вам понадобится. Диск дешевый.