3

The following works fine on Mac OS X:

#!/bin/bash
R CMD Sweave myfile.Rnw
pdflatex myfile.tex
open myfile.pdf

Now, I realize that these 3 lines of code are really helpful for my work – independently of some particular file. Thus I'd like to use the file as an argument. I know how to use an argument itself but have problems splitting the input after the string and concat it afterwards. If I was able to split the filename argument like:

split($1,".") # return some array or list ("name","ext")

Or is there a simpler, completely different way than using Python within a shell script?

Thx in advance for any general advice and examples as well !

Matt Bannert
  • 27,631
  • 38
  • 141
  • 207
  • Python scripting is nice because of much more explicit rules for character escaping. Actually, when I need a non-trivial script, I prefer python, which might be more verbose, but is definitely more unambiguous – Maxim Razin Aug 16 '10 at 19:42
  • Duplicate of all of the python/shell questions. Here's one: http://stackoverflow.com/questions/209470/can-i-use-python-as-a-bash-replacement. – S.Lott Aug 16 '10 at 19:44
  • @S.Lott, I knew this thread before posting and I agree that the general part is somewhat similar, but there's also a specific part which caused some interesting answers (e.g. Nathon). Sorry if the duplicate is annoying – it helped me. – Matt Bannert Aug 17 '10 at 07:52
  • @ran2: If it's distinct, then show precisely how this does **not** duplicate previous questions that look identical. This is a common question. http://stackoverflow.com/search?q=%5Bpython%5D+bash This last has 500 duplicates. Seriously. How is yours different. "Specific part" is vague. Update your question to be **specific** about the unique feature of your question, distinct from 500 copies. – S.Lott Aug 17 '10 at 10:19
  • @S.Lott you are right, it's pretty close. I tried to drop the general stuff, make the code a more focal point of the question – and accepted the most individual answer. HTH, don't think we should delete it, because several people but me enjoyed it. – Matt Bannert Aug 17 '10 at 10:38
  • @ran2: The title makes no sense at all. None. Zero. The answer is trivially "yes". The question does not match the title, since the question appears to be about parsing file names. If so, please (1) update the title, then (2) search Stack Overflow for `os.path.split` and then (3) close this question as a duplicate. – S.Lott Aug 17 '10 at 10:57
  • well, when I asked it, I was simply looking for that trivial yes. Now with all the help and people pointing me to interesting directions I would have stated it differently and maybe even realized that it was a duplicate. Changed the title though. – Matt Bannert Aug 17 '10 at 11:15
  • -1: "when I asked it, I was simply looking for that trivial yes". A dreadful waste of everyone's time. Please make the title actually reflect your **real** question, not a contrived, superficial, trivial and incorrect summary of your question. The title is still useless for other people with a problem similar to your **real** problem. Please help others by being focused and clear in your title. Please. – S.Lott Aug 17 '10 at 12:25
  • Ok. To me, I just did that now. I asked the best way I am able to. If that's not enough. To hell with this question. I never meant to annoy someone. – Matt Bannert Aug 17 '10 at 12:48

5 Answers5

6

I do all my shell scripting in python.
It's easier to read, more powerful and works on windows as well.

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
6

You could just take the base name as an argument and use $1.Rnw, $1.tex, and $1.pdf. Python is great for shell scripts, but I usually stick with bash for things less than 10 lines long.

If you really want to take a file name, you can use cut -f 1 -d '.' $1.

nmichaels
  • 49,466
  • 12
  • 107
  • 135
  • +1 this is really smart. Love it because, this works without any additional code I did not know before :) . Besides "Python is great for shell scripts, but I usually stick with bash for things less than 10 lines long" was just my intuition – am glad I was not too much off the mark. – Matt Bannert Aug 16 '10 at 20:40
  • kudos, the longer I think about it, I gotta accept this great answer. Thx for every else for sharing your thoughts. – Matt Bannert Aug 16 '10 at 20:47
2

The Python one liner would be:

python -c "print '$1'.split('.')[0]"

But Nathon's idea "Use the base name as the argument." is IMHO the best solution.

Edit:

You use "backticks" to use text that a program put on the standard output, like so:

eike@lixie:~> FOO="test.foo"
eike@lixie:~> BAR=`python -c "print '$FOO'.split('.')[0]"`
eike@lixie:~> echo $BAR

This should result in:

test
Eike
  • 2,205
  • 17
  • 10
1

I agree with Gerald's suggestion to use Makefiles, but his downside comment (dedicated makefile for each project) isn't quite correct, as Makefiles can be made more generic.

Replace $(FILE) with $@ and then invoke with "make foo".

I'd leave this as a comment to Gerald's answer but do not have the points to do so.

mankoff
  • 2,225
  • 6
  • 25
  • 42
  • Thanks for the comment - it's a good suggestion. Actually - I'm too lazy to do 'make foo' (well... not really - it's more of a habit). When initializing a new project, the makefile can be initialized automatically as well :) – Gerald Senarclens de Grancy Aug 16 '10 at 21:10
0

Python is certainly a good choice for shell scripting, however for a simple example as yours using bash is easier. Yet again, for compiling LaTeX I'd recommend a makefile and using GNU make. In case you haven't heard of it, you can do sth like this:

FILE = your_tex_filename
INCLUDES = preface.tex introduction.tex framework.tex abbreviations.tex 

all: $(FILE).pdf

$(FILE).pdf: $(FILE).tex $(INCLUDES) $(FILE).aux index bibliography
    pdflatex $(FILE).tex

index: $(FILE).tex
    makeindex $(FILE).idx

bibliography: $(FILE).bib $(FILE).aux
    bibtex $(FILE)

$(FILE).aux: $(FILE).tex
    pdflatex $(FILE).tex

# bbl and blg contain the bibliography
# idx and ind contain the index
.PHONY : clean
clean:
    rm *.aux *.bak $(FILE).bbl $(FILE).blg \
       *.flc *.idx *.ind *.log *.lof *.lot *.toc core \
       *.backup *.ilg *.out *~

and then simply compile your source document w/

make

or clean up after building w/

make clean

A downside is that you'd need a dedicated makefile for each of your projects, but w/ a template that is not much of an issue. hth

PS: A great introduction to string manipulation w/ the bash shell can be found at http://www.faqs.org/docs/abs/HTML/string-manipulation.html.