Question

I have markdown files formated like

chapter one
Blah, blah, blah.
chapter one-hundred-fifty-three

And also files formatted like

CHAPTER ONE
Blah, blah, blah.
CHAPTER ONE-HUNDRED-FIFTY-THREE 

In both cases I want to capitalize the chapter lines to say

# Chapter One
Blah, blah, blah.
# Chapter One-Hundred-Fifty-Three

I want to use sed (or awk or possibly some other linux cli program that pipes input and output)

I've found solutions to cap every word in a file but I'm not sure how to restrict it to specific lines or how to include words-connected-with-dashes-instead-of-whitespace

Was it helpful?

Solution

Using GNU sed, use an address (indicating the target line number) to tell it to apply the substitution to the desired line. For example to apply the substitution to the first line:

sed -r '1s/(\w)(\w*)/\U\1\L\2/g' file

To apply the substitution to the third line:

sed -r '3s/(\w)(\w*)/\U\1\L\2/g' file

To apply the substitution to both the first and third lines:

sed -r -e '1s/(\w)(\w*)/\U\1\L\2/g' -e '3s/(\w)(\w*)/\U\1\L\2/g'

If you don't mind the second line being modified, you can use an address range:

sed -r '1,3s/(\w)(\w*)/\U\1\L\2/g'

EDIT:

As per comments below:

sed -r '/^chapter/I { s/^/# /; s/(\w)(\w*)/\U\1\L\2/g }' file

Results:

# Chapter One
Blah, blah, blah.
# Chapter One-Hundred-Fifty-Three
# Chapter One
Blah, blah, blah.
# Chapter One-Hundred-Fifty-Three

OTHER TIPS

I'd do something like that in Perl:

#!/usr/bin/perl

while(<>) {
  if(/^chapter/i) {
    $_ = join " ", map ucfirst, split / /, lc;
    $_ = join "-", map ucfirst, split /-/;
  }
  print;
}

Call this like e.g. perl script < input-text > capitalized-text. My Perl-fu is a but rusty, I'm sure somebody will fold this into a oneliner called as an argument.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top