0

I'm looking to batch compress some pdfs, using the convert to/from ps trick outlined elsewhere. I have a function defined in an .zshrc file:

function pdfcompress() { for f in "$1"; do echo "compressing $1" pdf2ps "$f" "$f".ps ps2pdf -dPDFSETTINGS=/default "$f".ps "$f" rm "$f".ps done } 

My understanding is that I should be able to pass this a list of pdfs, and it compresses them. However, the following happens:

% ls | pdfcompress compressing Error: /undefinedfilename in --findlibfile-- Operand stack: () Execution stack: %interp_exit .runexec2 --nostringval-- findlibfile --nostringval-- 2 %stopped_push --nostringval-- findlibfile findlibfile false 1 %stopped_push findlibfile 1815 1 3 %oparray_pop findlibfile Dictionary stack: --dict:743/1123(ro)(G)-- --dict:0/20(G)-- --dict:85/200(L)-- Current allocation mode is local GPL Ghostscript 10.04.0: Unrecoverable error, exit code 1 GPL Ghostscript 10.04.0: Device 'pdfwrite' requires an output file but no file was specified. **** Unable to open the initial device, quitting. 

It seems that none of the file names are getting passed, for some reason. I've also tried approaches with find . -iname "*.pdf" -exec pdfcompress, and piping to xargs pdfcompress, but neither of those work because the function isn't in the environment. Other times the placeholder variables seem to be interpreted as literal strings.

I've been trying to get this to work in some form for over an hour with no luck. Any tips?

I have a folder structure of pdfs that I would like to maintain, so a solution that works recursively within directories would be best, if possible.

Thank you!

1
  • 2
    Possible example (a search on 'loop files zsh' should turn up more): stackoverflow.com/a/28604257. Your function should have for f in "$@", and should be invoked with pdfcompress * (or pdfcompress **/* for a recursive search). Be sure to test it with print statements (e.g. print pdf2ps "$f" "$f".ps) instead of diving straight in with something that could overwrite and destroy the input files. Commented Feb 21 at 20:47

1 Answer 1

3

You are mixing argument passing via stdin with passing them on the command line.

To pass via stdin (ls | pdfcompress), use

function pdfcompress() { while read f; do echo "compressing $f" ... 

To pass as arguments (pdfcompress *.pdf, or pdfcompress **/*.pdf), use

function pdfcompress() { for f in "$@"; do echo "compressing $f" ... 

PS: Piping from ls is a bad idea (see Why *not* parse `ls` (and what to do instead)?).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.