Что было неправильно, так это то, что я пытался записать в тот же файл, из которого я читал. Поэтому, когда вы используете > для записи в файл, когда файл открывается, он усекается, прежде чем sed сможет поместить в него содержимое, и поэтому файл пуст (это то, что я думаю, поправьте меня, если я ошибаюсь). Подобная логика, должно быть, объясняет, почему tee работает так неэкспе(ти)риментально.
Наконец, решение, предложенное другом из stackoverflow, помогло решить эту проблему гораздо проще.
paste -d, output.txt <(grep -oP '[0-9.]+(?=%)|[0-9.]+(?=[A-Z]+ of)' source.txt) > tmp ; mv tmp output.txt
Итак, чтобы предотвратить возникновение проблемы грязного чтения, использовался временный файл. Спасибо всем за помощь.