【问题标题】:Applescript+Shell Compare list of folders to list of files and move files into subfoldersApplescript+Shell 将文件夹列表与文件列表进行比较并将文件移动到子文件夹中
【发布时间】:2014-02-18 04:13:41
【问题描述】:

我正在尝试创建一个将运行下面的 bash 脚本的 applescript。将任何名为 temp_m 的文件移动到具有匹配名称的文件夹中。截图供参考。 applescript 的好处是用户可以轻松选择“松散图像”(源)文件夹和构建(归档)文件夹。它们通常存在于不同的位置,有时位于服务器/共享上。

例如来自

set myFolder to (choose folder)
set pFolder to POSIX path of myFolder
set folderNames to paragraphs of (do shell script "

PARENTDIRECTORY="pFolder"
find . -name "*.jpg" | while read file
do
   temp_m=$(basename "$file" .jpg)
   look=$(echo "$PARENTDIRECTORY/*/*${temp_m}" | sed 's/ /\\ /g') #I need to match all     subfolders in this parent folder that have the same name as temp_m name
   look=$(eval echo $look)
   if [ -f "$look" ]
   then
       todir="${look%/*}"
       echo mv "${temp_m}.jpg" ${todir}/ # echo action to perform - after testing remove echo
   else
       echo "No unique match for $file ($look)"
   fi
done

【问题讨论】:

    标签: bash shell applescript


    【解决方案1】:

    您可能只使用这样的 shell 命令:

    shopt -s nullglob;for f in ~/Pictures/loose\ files/*.jpg;do f2=${f##*/};d=~/Pictures/*/*/*/*/${f2%_*};[[ $d ]]&&echo mv "$f" $d;done

    shopt -s nullglob 使不匹配任何文件的文件名模式扩展为空字符串。 ${f##*/}f 的开头删除最长的*/ 模式,${f2%_*}f2 的末尾删除最短的_* 模式。 [[ $d ]] 等价于[[ -n $d ]],或者它测试是否设置了$d 并且没有设置为空字符串。

    如果目标文件夹可以处于不同的嵌套级别,可以使用find

    for f in ~/Pictures/loose\ files/*.jpg;do f2=${f##*/};d=$(find ~/Pictures -type d -name ${f2%_*});[[ $d ]]&&echo mv "$f" $d;done

    【讨论】:

    • +1 表示简洁,尽管您可能想使用[[ -d $d ]] 来确保只有一个目录匹配;另外,我建议你在 mv 命令中双引号 $d
    【解决方案2】:

    你的 bash 代码有几个问题;这是一个经过清理的版本,它会根据您的描述和屏幕截图尝试我认为您正在尝试做的事情:

    # Set the source and target [root] dir as POSIX paths.
    # Do NOT quote spaces here - this will be done below - but
    # note that, if applicable, you must use the explicit home-directory
    # path rather than '~'.
    tell application "System Events"
      set SOURCEDIRECTORY to "."
      # Example: Set to ~/Pictures/Archive
      set PARENTDIRECTORY to POSIX path of home folder & "/Pictures/Archive"
    end tell
    
    # Set the level in the target subdirectory hierarchy at which the 
    # specific target directories are located.
    set SUBDIRLEVEL to 4
    
    do shell script "
    SUBDIRLEVEL=" & SUBDIRLEVEL & "
    SOURCEDIRECTORY=" & quoted form of SOURCEDIRECTORY & "
    PARENTDIRECTORY=" & quoted form of PARENTDIRECTORY & "
    
    find \"$SOURCEDIRECTORY\" -type f -name \"*.jpg\" | while read file; do
    
      # Determine the subdir name prefix - everything before
      # the first \"_\" - with the extension stripped in any event.
      temp_m=$(cut -d '_' -f 1  <<<\"$(basename \"$file\" .jpg)\")
    
      # At the specified subdir level, find subdirs. of \"$PARENTDIRECTORY\"
      # whose name matches the prefix.
      matches=$(find \"$PARENTDIRECTORY\" \\
               -mindepth $SUBDIRLEVEL -maxdepth $SUBDIRLEVEL \\
               -type d -name \"${temp_m}\")
    
      # Expected: exactly 1 match.
      # Note: As long as only 1 level of subdirs is matched, there is 
      #          no strict need to test for *more* than 1 match.
      if [[ -n $matches && $(wc -l <<<\"$matches\") -eq 1 ]]; then
        todir=$matches
        # echo action to perform - after testing, remove echo       
        echo mv \"$file\" \"${todir}/\" 
      else
        echo \"No unique match for $file ($temp_m)\"
      fi
    
    done
    "
    

    注意:

    • 此代码(作为您的原始代码)并非旨在简单地列出文件夹名称,因此do shell script 之前的set folderNames to paragraphs of 没有意义。
    • 子目录仅在指定的层次结构级别匹配。如果您需要更大的灵活性,请根据需要调整 -mindepth $SUBDIRLEVEL -maxdepth $SUBDIRLEVEL 选项(删除它们会搜索所有级别)。

    【讨论】:

    • 谢谢,虽然我仍然无法让 applescript 传递父目录 var 并运行 shell 脚本。
    • @user3305972:我更新了我的帖子,使用正确转义的 shell 命令传递给do shell 脚本,以及如何将变量值传递给 shell 命令的演示。 HTH。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多