如何查找运行脚本的 Ubuntu 服务器的资源

如何查找运行脚本的 Ubuntu 服务器的资源

如果有人能告诉我在哪里可以学到更多关于这类工作的知识,我将不胜感激。我有一些使用 php 编写脚本的经验,并且一直在学习 Linux(通过 SSH 和 SFTP 使用 Ubuntu 服务器 CLI 将文件移入和移出我的 VM)。

尝试批量处理多个目录中的多张图片。我使用的是 imagemagick,它一次只能处理一个文件。

我希望它从顶级目录开始运行,然后对脚本可以找到的所有 jpg 文件执行此作业。

伪代码 -

for all folders in the directory
  open folder
  check if folder "drawings" (if !exists) then {start the loop over} else :
    open drawings folder
    for each file in drawings
      if file is a jpg
        run this program on it (convert image.jpg -crop 713x470+5+3 output.jpg)

答案1

弄清楚了我需要做什么循环,只需要掌握循环语法。希望这可以帮助其他可能需要根据名称循环遍历子目录的人。

for dir in */
do
    for subdir in $PWD/"$dir"*/
    do
        if [ "$subdir" == $PWD/"$dir""Drawings"*/ ]
        then
            for file in "$subdir"*.jpg
            do
                rm "$file"
            done

            for file in "$subdir"*.pdf
            do
                newName="${file/.pdf/}"
                convert -density 200 "$file" -append -resize 850 -background white -flatten "$newName".jpg
            done

            for file in "$subdir"*.jpg
            do
                newName="${file/.jpg/}"
                if [[ "$file" == *"insulation"* ]]
                then
                    convert "$file" -crop 820x710+15+97 "$newName-cropped.jpg"
                else
                    convert "$file" -crop 820x870+15+79 "$newName-cropped.jpg"
                fi
            done
        fi
    done
done
exit 0

答案2

这就是我想出的

#!/bin/bash
dnames=$(for i in $(ls -d $1*/); do echo ${i}; done)
if [ "$#" -eq "1" ]; then
    for dir in $dnames
    do
            cd $1
            cd $dir
            if [ -d "drawings" ]; then
                    cd drawings
                    jpgfiles=$(ls -p | grep -v / | awk '/.jp[e]?g/{print $0}')
                    if [ -z "$jpgfiles" ]; then
                            echo "Directory drawings exist in $dir but no .jpg images were found"
                    else
                            for jpgs in $jpgfiles
                            do
                                    echo "found $jpgs in ${dir}drawings" #convert $jpgs -crop 713x470+5+3 output.jpg
                            done
                    fi
            else
                    echo "Directory drawings cannot be found in $dir"
            fi
    done
else
    echo "A full path to the directory must be given"
    echo "For instance, /home/user1/Pictures/"
fi

这应该使用一个参数来运行,其中参数是目录的完整路径。例如,如果我要查找该图纸文件夹可能位于我的子目录中/主页/joram/目录

它会像这样

myprogram /home/joram/

程序循环/主页/joram/遍历其包含的所有目录。然后它访问/主页/joram/希望找到图纸子文件夹。当程序发现图纸包含 .jpg 图片的文件夹,命令就会被触发。完成命令后,只要检查完所有目录,程序就会继续循环。

程序输出示例:

#Directory drawings cannot be found in /home/joram/Desktop/
#Directory drawings cannot be found in /home/joram/Documents/
#Directory drawings exist in /home/joram/Downloads/ but no .jpg images were found
#Directory drawings cannot be found in /home/joram/Music/
#Directory drawings cannot be found in /home/joram/my_scripts/
#found test2.jpeg in /home/joram/Pictures/drawings
#found test.jpg in /home/joram/Pictures/drawings
#Directory drawings cannot be found in /home/joram/Public/

笔记:在当前形式下,该程序仅打印它找到的 .jpg 文件并提供一些其他信息(没有触发其他命令)。这样,可以在执行实际操作之前对其进行测试。要使程序获得您想要的内容,请删除 echo 部分并取消注释第 16 行的命令(如果这是您想要运行的实际命令)。

可以做出改进,希望这对您有所帮助!

答案3

算法是否必须完全相同,还是你只关心结果?因为我认为如果你使用find目录遍历和搜索,你可以创建更短更简单的代码:

find /path/to/search-root -path '*/drawings/*.jpg' -execdir convert -crop 713x470+5+3 {} output.jpg \;

这将查找所有*.jpg名为目录的(孙)子文件drawings,并在这些文件上运行convert命令。后者将output.jpg在与源文件相同的目录中生成一个文件。如果同一目录中有多个源文件,则前一个output.jpg实例将被覆盖。

如果您想要不同的、“唯一”的输出文件名,以便不覆盖之前的结果,则需要以某种方式转换输出文件名。不幸的是,我们find无法做到这一点,但我们可以将该任务委托给 shell。有多种方法可以实现这一点,但我通常更喜欢管道而不是循环,while read因为它比转义特殊字符更不烦人:

find /path/to/search-root -path '*/drawings/*.jpg' -print0 |
while IFS= read -rd '' f; do
  convert -crop 713x470+5+3 "$f" "${f%.*}.output.jpg"
done

(这需要一个支持read -dBash 之类的 shell。如果您需要更便携的替代方案,请这么说。)

相关内容