I have a linebreak-separated list of file paths, all to pdf files. I would like to filter out all those which have a corresponding *.tex file in the same directory (and so can be presumed auto-generated).

For instance, if the list includes foo.tex, foo.pdf, bar.pdf, I would like the script to output just bar.pdf. If I have foo/foo.tex and bar/foo.pdf, I would like the script to output bar/foo.pdf.

(The use-case is as described in this question: I have a git repository containing both tex files and externally produced pdfs. The auto-generated pdfs should not be tracked by git, but others should be. The solution I have in mind is to put *.pdf in the .gitignore, but add a git post-commit hook which warns me when there are untracked pdfs other than those generated from .tex files. I am getting the list of untracked pdfs with git status --ignored *.pdf, but am not sure how to cleanly implement this next step.)


You can just use a regular loop with [ -e and ${xxx%.pdf} to check for and construct the filenames. This reads the paths on standard input, one per line:

while read path
    [ -e "${path%.pdf}.tex" ] || echo "$path"

"${path%.pdf}" expands to $path with ".pdf" stripped off the end, and then we can put the ".tex" on the end directly. If it -exists then we do nothing, and otherwise (||) it prints out the path to the PDF. You could put more complicated logic and behaviour in there if you wanted.

The usual caveats about the value of IFS and filenames containing newlines, etc, apply, but assuming that you have nothing unusual going on that all works straightforwardly.

| improve this answer | |

Your Answer

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

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