Reputation: 1931
I have a command that take data through stdin and produce output on stdout. I need a wrapper for that command that would only output the diff between the input and output. Preferably without using temp files or name pipes, and I need it to work with macOS shells.
I now I can diff the output of 2 commands with diff <(cmd1) <(cmd2)
and I now I could split the input into 2 streams with tee
, but I'm not sure if I can somehow connect those 2 things to achieve what I want.
Described as a diagram, I want this:
/---> process --->\
stdin-->+ diff ---> stdout
\---------------->/
Upvotes: 1
Views: 43
Reputation: 46876
I thought at first it might be fun to hand fo process in a coproc
command, but that proved unnecessarily complex for the wrapper. Instead, I have this.
First, the script that modifies some lines (which I've called change
):
#!/usr/bin/env bash
while read -r -s ; do
case "$REPLY" in
*[abc]*) printf '%s\n' "${REPLY^^}" ;;
*) printf '%s\n' "${REPLY}" ;;
esac
done
This script runs in a more current version of bash than ships with macos, but that doesn't matter, it's only an example.
And the wrapper (which I've called thing
):
#!/bin/bash
text="$(cat)"
diff <he(echo "$text") <(change <<< "$text" )
And if you're looking for only the words that have chamged,yo might use the following to replace the diff
line:
comm -13 <(echo "$text") <(change <<< "$text" )
This script is simple enough that is will run in zsh as well without chamges.
Upvotes: 0
Reputation: 204381
diff <(cmd1) <(cmd2)
uses temp files and it sounds like you're OK with that so it's not clear why say you want to avoid temp files. I'd just keep it simple and use a temp file:
$ cat tst.sh
#!/usr/bin/env bash
tmpIn=$(mktemp) || exit 1
trap 'rm -f "$tmpIn"; exit' EXIT
tee "$tmpIn" |
sed 's/foo/bar/g' |
diff "$tmpIn" -
$ printf 'this\nfoo\nis\nfoo\nit\n' | ./tst.sh
2c2
< foo
---
> bar
4c4
< foo
---
> bar
The sed
command is obviously a placeholder for whatever your process
command is.
Upvotes: 2