Again I am attempting to alter configuration file via script.

I looked into jq but jq seems to support the .json format alone.

.vdf is almost exactly like .json except that there are no commas.

here is an attempt at what I want to do but with sed.


text_to_find='                  "9420"
                        "LastPlayed"        ".*"
text_to_put='                   "9420"
                        "LastPlayed"        "1554153269"
                        "ViewedLaunchEULA"      "1"
                        "ViewedSteamPlay"       "1"
                        "BadgeData"     "02000000080b"
                        "LaunchOptions"     "PROTON_NO_ESYNC=1, PROTON_DUMP_DEBUG_COMMANDS=1 %command%"
sed -i "s|$text_to_find|$text_to_put|1" myTestFile 

that returns: "sed: -e expression #1, char 13: unterminated `s' command"

and it probably would fail to match Last played because I don't think in this context ".*" would still be interpreted.

here's an example of the test file :


  • it's not JSON. as specifically stated. it is VDF. so again not JSON
    – tatsu
    Apr 15, 2019 at 10:05
  • Not sure, but the first thing I would try would be to use another separator instead of a vbar which the shell might think is a pipe symbol. Looking further, I don't believe the shell recognizes nested quotes, so the first one in your variable value ends the sed command prematurely.
    – Joe
    Apr 20, 2019 at 4:34
  • Something a bit touchy like this is probably easier to do in a language other than sed. sed is totally unforgiving and uncommunicative when it fails making debugging challenging. I would do this in awk because: you can break up complex changes into simpler steps and you can add print statements to view partial results.
    – Joe
    Apr 20, 2019 at 4:39

1 Answer 1


One way to get around this would be to use multiple sed steps to get all the double quotes out of the way.

In the first one you'd replace all double quotes in the target file with a tag character such as @. It has to be a character or string guaranteed not to be present in the original.

Then, you'd do your substitution using source and target strings like your originals, but with all the quotes replaced with the tag character in both strings.

Finally, you'd replace all tag characters with double quotes.

As for the .*, it's sort of a cake and eat it situation. If it's not quoted, bash will eat it and if it is quoted, sed will see it as a literal. You may have to rewrite this part using a regex that will survive being quoted in bash but take effect in sed.

That's why I said it would probably be easier in awk. ;) Especially the last part!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .