转换指定分机的所有文件的目录到PDF中,递归所有子目录

问题描述 投票:0回答:2

我使用下面的代码(从this answer)所有CPP文件转换在当前目录到文件名为code.pdf和它工作得很好:

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

我想提高这个脚本:

  1. 使其可以采取一个参数指定所述扩展名而不是具有它的硬编码到CPP的sh文件;
  2. 有它递归运行,访问当前目录的所有子目录;
  3. 对于遇到的每个子目录,指定扩展名的所有文件转换为名为$ NameOfDirectory $ .PDF,并放置在子目录一个单一的PDF;
linux bash find xargs enscript
2个回答
1
投票

首先,如果我理解正确的话,这个要求:

对于遇到的每个子目录,指定扩展名的所有文件转换为名为$ NameOfDirectory $ .PDF一个单一的PDF

是不明智的。如果这意味着,比方说,a/b/c/*.cpp被enscripted到./c.pdf,那么你,拧如果你也有a/d/x/c/*.cpp因为这两个目录内容映射到相同的PDF。这也意味着,*.cpp(在当前目录即CPP文件)被enscripted到一个文件名为./..pdf

这样,根据所需的扩展,它的名字的PDF,并将其放置在每个子目录沿着它的源文件的东西,没有这些问题:

#!/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

1
投票

首先,如果我理解正确的,你用的是什么,其实是错误的 - find将会从所有子目录检索文件。递归工作,只有从当前目录中获取文件(我把它命名为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

该检查是确保一个与实际存在的分机或子目录文件。该脚本运行在当前目录下,并递归调用自己 - 如果你不想要一个完整的路径,把它放到你的PATH列表,但一个完整的路径是好的。

© www.soinside.com 2019 - 2024. All rights reserved.