I have a documen with headers in ALL CAPS, for example:

       env - run a program in a modified environment

and I want to insert


before the header and

] \hfill \\

after a header so that the result will be like:

\item[NAME] \hfill \\
       env - run a program in a modified environment

I wrote a sed script to add LaTeX formatting for most of the document, but this line of my script is not working properly:

s/\([A-Z]\)*/\\item\[&\] \\hfill \\\\/g

Instead of producing the desired output (above example), I am getting:

...\item[NAME] \hfill \\
\item[] \hfill \\ \item[] \hfill \\ \item[] \hfill \\ \item[] \hfill \\ \item[] \hfill \\ \i$
\item[] \hfill \\

As you can see, it correctly inserts the formatting around the HEADER, but also replaces everything else in the document. How can I fix this?

  • 1
    Try moving the *before \) – enzotib Sep 11 '13 at 5:51
  • @enzotib didn't work - it's adding the latex formatting to the beginning of every line, not just the headers – user46865 Sep 11 '13 at 6:03
  • you need a way (a regex pattern) to select that line, then change the sed command to /pattern/s/something/subs/. Also the line number N could be used: Ns/something/subs/ – enzotib Sep 11 '13 at 6:05
  • @enzotib I would use line numbers but I am writing a script that should be able to processes several man pages and convert them to latex documents... Any ideas on the proper regex pattern to identiy that line? I think it should be a regex something like "an all capitals word on a line by itself with nothing before or after it" so... something like s/^[A-Z]$/subs would that work? – user46865 Sep 11 '13 at 6:12
  • 2
    \+ is a GNU sed extension the means "one or more", as opposed to * meaning "0 or more". The general form of the "s" command is "Address s / pattern / subs / options". Address can be a line number or range or a regex or a range specified by two regex. Without an Address, the substitution apply to all lines. – enzotib Sep 11 '13 at 6:30

See above comment thread for the answer. TL:DR the answer is:

s/^\([A-Z]\)\+$/\\item\[&\] \\hfill \\\\/
  • If you use & (= everything that's matched) in the replacement part, you can omit \( and \) in the pattern. The grouping parentheses are only necessary if you want to refer to a substring using \1,...,\9 in the replacement part. – Uwe Sep 11 '13 at 9:27
  • I was just wondering about that! Thanks! So if I had two groups then I could reference them with \1 and \2? – user46865 Sep 11 '13 at 10:10
  • Yes, exactly. \1,...,\9 refer to the string that is matched by the 1st,...,9th parenthesized subexpression; & refers to the entire string that is matched. – Uwe Sep 11 '13 at 13:17

If the line you want to modify is always the first (as it seems from your question and comments), you can use AWK to make it easier.

    if (NR == 1)
   { print "\\item[" $0 "] \\hfill\\\\" }
   { print ($0)}

Run it as awk -f myScript.awk myManPage > myLaTeXmanPage.

  • 1
    You are misusing awk, your code could be 'NR==1 { print "\\item[" $0 "] \\hfill\\\\" }NR>1' – Bernhard Sep 11 '13 at 7:42
  • 1
    That is terser, but I tend towards clearer answers when answering questions unix.SE. IMHO they are more useful. Many Unix users are not familiar with awk, and they appreciate something they can easily understand (and maybe adapt) rather than some obscure recipe. – sergut Sep 11 '13 at 10:14
  • This is not obscure, this is some of the vary basics of awk: codeblocks with a conditional statement. Also, I disagree your answer is clearer. – Bernhard Sep 11 '13 at 10:33

Looks like you're trying to TeXify some man pages. Have you looked at Pandoc? It's a "universal document converter" that understands both the LaTeX and man formats, among many others.

In fact, if your end goal is to produce PDF man pages, man itself can do that for you. For example, to get a PDF version of the bash(1) page:

man -T ps bash|ps2pdf - bash.pdf

ps2pdf is part of the ghostscript package.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy