简体   繁体   中英

Convert all files of a specified extension within a directory to pdf, recursively for all sub-directories

I'm using the following code (from this answer ) to convert all CPP files in the current directory to a file named code.pdf and it works well:

find . -name "*.cpp" -print0 | xargs -0 enscript -Ecpp -MLetter -fCourier8 -o - | ps2pdf - code.pdf

I would like to improve this script to:

  1. Make it a .sh file that can take an argument specifying the extension instead of having it hardcoded to CPP;

  2. Have it run recursively, visiting all subdirectories of the current directory;

  3. For each subdirectory encountered, convert all files of the specified extension to a single PDF that is named $NameOfDirectory$.PDF and is placed in that subdirectory;

First, if I understand correctly, what you are using is in fact wrong - find will retrieve the files from all sub-directories. To work recursively, only getting files from the current directory (I named it do.bash ):

#!/bin/bash

ext=$1
if ls *.$ext &> /dev/null; then
    enscript -Ecpp -MLetter -fCourier8 -o - *.$ext | ps2pdf - $(basename $(pwd)).pdf
fi
for subdir in */; do
    if [ "$subdir" == "*/" ]; then break; fi
    cd $subdir
    /path/to/do.bash $ext
    cd ../
done

The checks are to make sure a file with the extension or a sub directory actually exist. This scripts operates on the current directory, and calls itself recursively - if you do not want a full path, put it in your PATH listings, though a full path is fine.

First, if I understand it correctly, this requirement:

For each subdirectory encountered, convert all files of the specified extension to a single PDF that is named $NameOfDirectory$.PDF

is unwise. If that means, say, a/b/c/*.cpp gets enscripted to ./c.pdf , then you're screwed if you also have a/d/x/c/*.cpp , since both directories' contents map to the same PDF. It also means that *.cpp (ie CPP files in the current dir) gets enscripted to a file named ./..pdf .

Something like this, which names the PDF according to the desired extension and places it in each subdirectory alongside its source files, doesn't have those problems:

#!/usr/bin/env bash
# USAGE: ext2pdf [<ext> [<root_dir>]]
# DEFAULTS: <ext> = cpp
#           <root_dir> = .
ext="${1:-cpp}"
rootdir="${2:-.}"

shopt -s nullglob

find "$rootdir" -type d | while read d; do

  # With "nullglob", this loop only runs if any $d/*.$ext files exist
  for f in "$d"/*.${ext}; do

    out="$d/$ext".pdf
    # NOTE: Uncomment the following line instead if you want to risk name collisions
    #out="${rootdir}/$(basename "$d")".pdf

    enscript -Ecpp -MLetter -fCourier8 -o - "$d"/*.${ext} | ps2pdf - "$out"

    break   # We only want this to run once

  done

done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM