Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a folder full of files with a .dot extension like this:


I want to go through all the files in this folder and run a command on them such as this:

dot -Tpdf a.dot -o a.pdf
dot -Tpdf b.dot -o b.pdf
dot -Tpdf c.dot -o c.pdf

I am guessing that I need to use the vertical bar and do a command like this:

ls *.dot | dot -Tpdf ... -o ....pdf

But I don't know how to make the pipe place each file onto the middle part only. Should I be using xargs? Furthermore, how to strip the extension then also place it onto the second part. If I could be at least pointed in the right direction (which shell command to use) it would help me very far along the way to figuring this out.

share|improve this question
Do not parse the output of ls. The shell performs wildcard expansion (e.g. of *.dot into a.dot b.dot c.dot); ls is a tool intended for humans, when you want to display file attributes (size, date, etc.). – Gilles Feb 27 '12 at 2:09
up vote 6 down vote accepted


for i in *.dat ; do dot -Tpdf "$i" -o "$(basename "$i" dot)pdf" ; done

EDIT: Correct handling of filenames with whitespaces.

share|improve this answer
@Peter.O BTW, my origin answer without quotes works correctly in zsh, which I use, even for filenames with whitespaces. – jofel Feb 23 '12 at 16:58
Thanks for pointing that out. In general, unless specifically stated, as you have now done, it is typically better to present the most portable syntax. POSIX being the definitive standard... – Peter.O Feb 23 '12 at 22:45

xargs is another method to iterate over a set of filenames. However, you don't have the same flexibility as a for-loop to manipulate the filename in each iteration:

ls *.dot | xargs -n1 -I FILE echo dot -Tpdf FILE -o FILE.pdf

will result in

dot -Tpdf a.dot -o a.dot.pdf
dot -Tpdf b.dot -o b.dot.pdf
dot -Tpdf c.dot -o c.dot.pdf
share|improve this answer

If you are a fan of awk and sed you can also achieve this with

ls *.dot | awk '{print("dot -Tpdf "$1" -o "$1)}' | sed 's/.dot/.pdf/2' | sh
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.