maxpe
maxpe

Reputation: 316

Edit stderr before writing it to file together with stdout

I went through many SO questions but so far I couldn't find one that addresses my particular problem.

I use GNU date to convert dates into epoch times:

date -f created_at +%s > created_at_epoch

To catch error messages like "date: invalid date ‘...’" I redirect stderr to stdout:

date -f created_at +%s 2>&1 > created_at_epoch

Now, I would like to change the error message into something like "NA". I tried process substitution but this doesn't seem to work. The order of the lines in the output is changed and the process doesn't finish.

date -f created_at +%s 2> >(sed s/^date.*/NA/ >&1) > created_at_epoch

I would be very glad for any suggestions on how to solve this, I am not getting my head around this.

Upvotes: 1

Views: 344

Answers (2)

John Kugelman
John Kugelman

Reputation: 361645

Normally I would use the process substitution method you tried, but I wouldn't here since you care about output order and there's no guarantee in general that stdout and stderr will be correctly intermingled. You don't want to rely on them both being line buffered and being flushed regularly.

It would be better to process each line separately yourself. That way you can control exactly how bad dates are handled. As a bonus, you can suppress stderr entirely and just key off of date's exit code.

while IFS= read -r date; do
    date -d "$date" +%s 2>/dev/null || echo "N/A"
done <created_at >created_at_epoch

Upvotes: 3

Benjamin W.
Benjamin W.

Reputation: 52152

You can first redirect standard error to standard output, then manipulate the combined stream:

date -f created_at +%s |& sed '/date/s/.*/NA/' > created_at_epoch

|& is a Bash shorthand for 2>&1 |.

Upvotes: 2

Related Questions