0

I am looking for a BASH sed script that can open an .mdx file and search line by line and find the second line that has the value I'm searching for: three hyphens like this ---. Then, I'm hoping to insert two lines of redirect information above that second set of hyphens.

The second occurrence of these three hyphens could be on any line following line 1, so I would need a script that is smart enough to search until it finds the second one.

I'll need something that runs in the MacOS that can do some in-place file updates.

Here's my input file:

---
title: Some kind of title
---

I'd like to locate that second instance of three hyphens and insert new text above it like this:

---
title: Some kind of title
redirects:
  - /some/kind/of/directory/path
---

In my shell script, I have a variable that contains that redirect path, so I would somehow need to pass that variable along with a hard-coded redirects: to sed.

I looked at a variety of options, including the POSIX option included here, but it just deletes the second occurrence. Perhaps there's an easy way I could modify that to update?

Let me know if you need more to understand what I'm looking for.

  • 1
    Please, post a full testable sample data with the expected output. Don't post them as comments or images. Thanks. – James Brown Apr 21 '21 at 04:43
  • Is there a particular reason you want to use BASH? Other languages such as Python or Perl might be better suited (if not easier to implement) for this task. – Donna Apr 21 '21 at 04:55

3 Answers3

1

This is one way of doing it:

testpath="/some/kind/of/directory/path"
sed "s|---|redirects:\n\ \ -\ $testpath\n---|" file.mdx | sed '/---/,$!d'

This works by adding the "redirect: path" directly above both "---" lines, then deletes the top "redirect: path". This will fail miserably if there is more than two "---" in the file.

To do it inline:

testpath="/some/kind/of/directory/path"
sed -i .bak "s|---|redirects:\n\ \ -\ $testpath\n---|" test.txt && sed -i _bak2 '/---/,$!d' test.txt
jared_mamrot
  • 22,354
  • 4
  • 21
  • 46
1

You can find out the line number of the 2nd --- and then insert before that line.

Example (tested on macos):

$ cat file
---
title: Some kind of title
---
$ cat foo.sh
path=/some/kind/of/directory/path
n=$( sed -n '/^---$/=' file | sed -n 2p )
sed -e "$n i\\
redirects:\\
 - $path
" file
$ bash foo.sh
---
title: Some kind of title
redirects:
 - /some/kind/of/directory/path
---
$

(Use sed -i for updating the file in place.)

pynexj
  • 19,215
  • 5
  • 38
  • 56
  • This option worked well, but I noticed that if I added the "-i" to modify in place, SED still creates backup files. In this case, it was appending the "-e" to the file (file-e) which I found unusual. I can add the "-i'.bak' -e" to control this backup extension, but is it true that SED on the MacOs requires backup files (unlike GNU SED)? – rhetoric101 Apr 26 '21 at 18:27
  • 1
    use `-i ''` if you don't want to create the bak file. – pynexj Apr 26 '21 at 23:29
-1

Are you hellbent on using sed for this? Generally Awk is both more versatile and more readable.

awk '/^---$/ { print; hyphens=1; next }
    hyphens && /^title: / { print; print "redirects:\n  - /some/kind/of/directory/path"; next }
    { hyphens=0 } 1' file.mdx >newfile.mdx

In brief, we keep track of whether the previous line was three hyphens; if it was, and the current line matches the regex ^title: , print the additional lines. Otherwise, we reset the state variable and print. (The final 1 is a common Awk idiom to avoid having to say { print } explicitly.)

Unfortunately, standard Awk has no -i option. If you can use GNU Awk, it has an option -i inplace which emulates the (also nonstandard, but common) -i option of sed. Otherwise, just write to a temporary file and move it back onto the original afterwards; that's what -i does behind the scenes, too.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • If there could be more than one line before the second set of triple hyphens and/or the regex `^title: ` might not match the lines you want, it's not hard to switch around things to look for the next occurrence of triple hyphens. – tripleee Apr 21 '21 at 04:47