将名称中带有模式的文件移动到与其名称具有相同模式的文件夹
Moving files with a pattern in their name to a folder with the same pattern as its name
我的目录包含数百个与此类似的文件和目录:
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
在 Unix 中请使用下面的命令
find . -name '*508471*' -exec bash -c 'echo mv [=10=] ${0/508471/598690}' {} \;
#!/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
) 的每个文件,将其移动到相应的目录。
如果您不确定这会做什么,请在 &&
和 mv
之间放置一个 echo
,它将列出脚本将执行的 mv
操作。
记住,do not parse ls
。
下面的代码应该可以完成所需的工作。
for dir in */; do find . -mindepth 1 -maxdepth 1 -type f -name "*${dir%*/}*.pdf" -exec mv {} ${dir}/ \;; done
其中 */
将仅考虑给定目录中存在的目录,find
将仅搜索给定目录中与 *${dir%*/}*.pdf
匹配的文件,即包含目录名称的文件名它的子字符串和最后的 mv
会将匹配的文件复制到目录中。
您可以在这些 pdf 文件和目录的父目录中使用此 for
循环:
for d in */; do
compgen -G "*${d%/}*.pdf" >/dev/null && mv *"${d%/}"*.pdf "$d"
done
compgen -G
用于检查给定的 glob 是否匹配。
我的目录包含数百个与此类似的文件和目录:
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
在 Unix 中请使用下面的命令
find . -name '*508471*' -exec bash -c 'echo mv [=10=] ${0/508471/598690}' {} \;
#!/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
) 的每个文件,将其移动到相应的目录。
如果您不确定这会做什么,请在 &&
和 mv
之间放置一个 echo
,它将列出脚本将执行的 mv
操作。
记住,do not parse ls
。
下面的代码应该可以完成所需的工作。
for dir in */; do find . -mindepth 1 -maxdepth 1 -type f -name "*${dir%*/}*.pdf" -exec mv {} ${dir}/ \;; done
其中 */
将仅考虑给定目录中存在的目录,find
将仅搜索给定目录中与 *${dir%*/}*.pdf
匹配的文件,即包含目录名称的文件名它的子字符串和最后的 mv
会将匹配的文件复制到目录中。
您可以在这些 pdf 文件和目录的父目录中使用此 for
循环:
for d in */; do
compgen -G "*${d%/}*.pdf" >/dev/null && mv *"${d%/}"*.pdf "$d"
done
compgen -G
用于检查给定的 glob 是否匹配。