1

How do I do something like this?

"input" | \

if
grep -E 'phone_and_fax":"Phone: .*  Fax:'
then
sed 's/phone_and_fax":"Phone:/|/g' | \
sed 's/  Fax:/|/g' | \
sed 's/original_license_date":"Original License Date:/|/g'
elif
grep 'phone_and_fax":"Phone: '
then
sed 's/phone_and_fax":"Phone:/|/g' | \
sed 's/original_license_date":"Original License Date:/||/g'
elif
grep '  Fax:'
then
sed 's/phone_and_fax":"Phone:/||/g' | \
sed 's/  Fax:/|/g' | \
sed 's/original_license_date":"Original License Date:/|/g'
else
sed 's/phone_and_fax":"Phone:/||/g' | \
sed 's/original_license_date":"Original License Date:/|/g'
fi | \

"continue script"

The point of what is being replaced or what is being looked for doesn't really matter. What I am trying to do is use some piping to handle some text, but if it runs across a certain pattern using grep with regex, then it needs to change what it will replace with that particular instance. But the grep should not change the output of the piping.

4
  • 2
    It would be more helpful to provide an exact example of what you are trying to do, as the one in your question seems a little contrived. Commented Oct 27, 2014 at 18:57
  • 1
    grep and sed both swallow input you can't have both of them operating in a single segment of a pipeline like this. Commented Oct 27, 2014 at 19:00
  • grep probably isn't needed at all. If s/is/IS/g doesn't match the string is, the input is passed through unchanged, so you don't need to check if is is present first. Commented Oct 27, 2014 at 19:06
  • @TomFenech I fixed it up Commented Oct 27, 2014 at 19:18

1 Answer 1

1

sed already has grep-like tests built-in to its syntax:

For example, take this pseudo-code:

if grep -E 'some.*xt'; then sed 's/some/SOME/g'; fi

It can be translated into a single call to sed. Observe:

$ echo some text | sed '/some.*xt/ s/some/SOME/g'
SOME text

Versus:

$ echo some test | sed '/some.*xt/ s/some/SOME/g'
some test

Longer example

Consider this pseudo-code:

if
grep -E 'some.*xt'
then
sed 's/some/SOME/g'
elif
grep 'is'
then
sed 's/is/IS/g'
fi | \
sed 's/This/""/g'

The equivalent sed statement is:

sed '/some.*xt/ {s/some/SOME/g; b fi}; /is/ s/is/IS/g; :fi; s/This/""/g'

The elif part of the pseudo-code is translated here to a branch statement. If the condition /some.*xt/ matches, then the substitution s/some/SOME/g is performed and b fi tells sed to jump to the label fi. This does the logical equivalent of the elif statement.

Examples illustrate this in operation:

$ echo "some text This is" | sed '/some.*xt/ {s/some/SOME/g; b fi}; /is/ s/is/IS/g; :fi; s/This/""/g'
SOME text "" is
$ echo "some test This is" | sed '/some.*xt/ {s/some/SOME/g; b fi}; /is/ s/is/IS/g; :fi; s/This/""/g'
some test ThIS IS
Sign up to request clarification or add additional context in comments.

2 Comments

This is great! I forgot to add one part to my question (I apologize for that) but what if, in the if command I want more than one replace to occur, but only if the value of the matched pattern is true, does this still work? or how to I run with that in the pipe command?
@double_j You can put as many replace (substitute) commands as you like after the condition by putting them in curly-braces, separated by semicolons: sed '/some.*xt/ {s/some/SOME/g; s/text/TEXT/;}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.