将名称中具有模式的文件移动到与名称具有相同模式的文件夹

时间:2020-03-13 17:45:44

标签: linux bash shell mv

我的目录包含数百个与此类似的文件和目录:

508471/
ae_lstm__ts_ 508471_detected_anomalies.pdf
ae_lstm__508471_prediction_result.pdf
mlp_508471_prediction_result.pdf
mlp__ts_508471_detected_anomalies.pdf
vanilla_lstm_508471_prediction_result.pdf
vanilla_lstm_ts_508471_detected_anomalies.pdf

598690/
ae_lstm__ts_598690_detected_anomalies.pdf
ae_lstm__598690_prediction_result.pdf
mlp_598690_prediction_result.pdf
mlp__ts_598690_detected_anomalies.pdf
vanilla_lstm_598690_prediction_result.pdf
vanilla_lstm_ts_598690_detected_anomalies.pdf

有些文件夹的名称是ID号,例如508471和598690。
在与这些文件夹相同的路径中,存在pdf个文件,该文件的名称中包含此ID号。我需要将名称中具有相同ID的所有pdf文件移动到其相关目录中。

我尝试了以下shell脚本,但是它什么也没做。我在做什么错了?
我试图遍历所有目录,找到名称中带有id的文件,然后将它们移至相同的目录:

for f in ls -d */; do
    id=${f%?}  # f value is '598690/', I'm removing the last character, `\`, to get only the id part 
    find . -maxdepth 1 -type f -iname *.pdf -exec grep $id {} \; -exec mv -i {} $f \;
done

4 个答案:

答案 0 :(得分:2)

#!/bin/sh
find . -mindepth 1 -maxdepth 1 -type d -exec sh -c '
    for d in "$@"; do
        id=${d#./}
        for file in *"$id"*.pdf; do
            [ -f "$file" ] && mv -- "$file" "$d"
        done
    done
' findshell {} +

这会找到当前目录中的每个目录(例如,找到./598690)。然后,它从相对路径中删除./,并选择包含结果ID(598690)的每个文件,并将其移至相应的目录。

如果不确定该怎么做,请在echo&&之间放置一个mv,它将列出脚本将执行的mv操作。

记住,do not parse ls

答案 1 :(得分:1)

下面的代码应完成所需的工作。

for dir in */; do find . -mindepth 1 -maxdepth 1 -type f -name "*${dir%*/}*.pdf" -exec mv {} ${dir}/ \;; done

其中*/仅考虑给定目录中存在的目录,find将仅搜索给定目录中与*${dir%*/}*.pdf匹配的文件,即,包含目录名作为其子目录的文件名-string,最后mv将匹配的文件复制到目录中。

答案 2 :(得分:0)

在Unix中,请使用以下命令

self.

答案 3 :(得分:0)

您可以在以下pdf文件和目录的父目录中使用此for循环:

for d in */; do
    compgen -G "*${d%/}*.pdf" >/dev/null && mv *"${d%/}"*.pdf "$d"
done

compgen -G用于检查给定的glob是否匹配。