Почему при перенаправлении вывода иногда создается пустой файл?

Да, спасибо @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>

А мне нужна каждая схема в отдельном файле.

3
14.05.2020, 14:06
3 ответа

Вы успешно нашли одну из вещей, которые вам не следует делать :-)Никогда не перенаправляйте на файл, над которым вы работаете!

A1 :хорошим ресурсом для изучения грамматики оболочки будет абсолютное руководство по написанию сценариев bash , IMO

A2 :Для скриптов bash -вы можете использовать set +xдля получения более подробного вывода, но я не знаю, как добиться того же на уровне «запускать вещи в подсказке» -.

A3 :Добавьте [solved]к условиям поиска -. Находит вам решение вашей проблемы, а не больше проблемы, которую вы уже знаете.

5
28.04.2021, 23:14

Рассмотрите 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
12
28.04.2021, 23:14

Одним из способов решения проблемы является точное изучение того, в каком порядке происходят перенаправления, расширения, подоболочки и т. д., чтобы вы могли обнаруживать ошибки такого типа до того, как они произойдут.

Я не рекомендую это делать. Вы все равно будете время от времени ошибаться, и стоимость может быть потеряна.

Лучше не доверять своей способности сохранить все это прямо и написать больше идиотского -кода подтверждения. Все мы иногда бываем идиотами.

Так

cp file.txt file.txt.old
cat file.txt.old | sed 's/a/1/' > file.txt

Это проще, поскольку нет зависимости от порядка событий, за исключением того, что строка 1 происходит перед строкой 2.

В качестве дополнительного преимущества он защищает от других ошибок, когда вообще не следовало запускать этот скрипт.

Цена этой практики заключается в том, что у вас будут .oldфайлы, лежащие повсюду. Это страховая премия, вы будете рады, что заплатили в тот день, когда она вам понадобится. Диск дешевый.

0
28.04.2021, 23:14

Теги

Похожие вопросы