Conditional sed substitution

bash

Solution

Taking your subject as a guide, here is one way to do it conditionally with sed:

sed -e '/^\s*ITEMS=/{s/=""/="$ITEM'"$itemNum"'"/;t;s/"$/ $ITEM'"$itemNum&/;}" file.txt

The main change is we try to substitute empty quotes ("") first. If that succeeds, the conditional branch t sends us to the end of the script, bypassing the other substitution. The second substitution only occurs if the first fails. I've changed the quoting to get rid of some of the "leaning toothpicks", but it's about 66% your original command.

Edit: The "leaning toothpicks" thing by OP's request

The original put the entire sed script line in double quotes so all " and most $ had to be escaped with backslashes. Rewriting my version like that looks like this:

sed -e "/^\s*ITEMS=/{s/=\"\"/=\"\$ITEM$itemNum\"/;t;s/\"$/ \$ITEM$itemNum&/;}" file.txt

I just find all those backslashes distracting, so I put as much of it into single quotes as I could, leaving only $itemNum in double quotes. In a shell script, if two strings are adjacent, they get stuck together so `var1=QRS; var2='ABC'$var1'XYZ'` leaves var2 set to 'ABCQRSXYZ' - if you think there's a chance the variable could contain a space, then it is best to quote it: `var1=QRS; var2='ABC'"$var1"'XYZ'` (no space between '" and "' in there.

Problem

Currently, I have a fully functional sed command that adds an item to a list in a specific text file in the following way ... ``` ITEMS="$ITEM1 $ITEM2 $ITEM3" ``` becomes the following when we wish to insert `$ITEM4` ... ``` ITEMS="$ITEM1 $ITEM2 $ITEM3 $ITEM4" ``` The number of items in the list is not known; it is dynamic. And the dollar signs and quotes in that text are to be taken literally. I use the following command to accomplish the addition to the list (variable `$itemNum` is assigned elsewhere) ... ``` sed "/^\s*ITEMS=/s/\"$/ \$ITEM$itemNum&/" file.txt ``` All this does, of course, is find the line starting with `ITEMS=` (and possibly with leading spaces) and replace the last double quote in that line with a space plus the desired item plus a double quote (to put the replaced double quote back in place). However, I have an additional case where the `ITEMS` list could be empty like so ... ``` ITEMS="" ``` and in this case, my command would insert `$ITEM4` at the end of the list like so ... ``` ITEMS=" $ITEM4" ``` However, I want my command to be able to account for an empty list and not put the leading space when the list is indeed empty, so it just looks like ... ``` ITEMS="$ITEM4" ``` How could I alter my existing command to best accomplish this?

Original source