我对使用 Linux 和终端还很陌生,但我遇到了一些问题。
我有大约 50 个父文件夹,全部包含子文件夹。一个子文件夹名为filtered_feature_bc_matrix
.在其他子文件夹中,有一些我想移动到子文件夹中的.mtx
文件。.tsv
filtered_feature_bc_matrix
所以我的架构是这样的
Mother_folder(containing all the 50 parent folders) ->
parent_folder
->filtered_feature_bc_matrix
->other_subfolder
->other_subsubfolder
files.mtx
我试过:
for dir in ./; do
$(find . -type f -name *.mtx -exec mv {} "./$dir/filtered_feature_bc_matrix" \;);
done
如果我cd
进入父文件夹,我会成功,但我有 50 个文件夹,所以我想了解如何自动执行此任务。
但我无法正确指定目标目录,这让我发疯;-)
我希望我说得清楚!
卡米尔
编辑:
当我执行代码时,我的文件matrix.mtx实际上没有移动到我想要的子文件夹中,而是移动到mother_folder中并重命名为filtered_feature_bc_matrix...
答案1
和zsh
:
autoload zmv
cd /path/to/mother/folder &&
zmv -n '*/^filtered_feature_bc_matrix/**/*.(mtx|tsv)(#q.)' \
'${f:h1}/filtered_feature_bc_matrix/${f:t}'
(-n
如果满意,请删除(试运行))。
使用find
类似 Bourne 或rc
-like 的 shell,您可以执行以下操作:
cd /path/to/mother/folder &&
LC_ALL=C find . \
'(' \
-name '.?*' -o \
-path './*/filtered_feature_bc_matrix' \
! -path './*/*/*' \
')' -prune -o \
-path './*/*/*' \
'(' \
-name '*.tsv' -o \
-name '*.mtx' \
')' -type f \
-exec sh -c '
ret=0
for file do
parent=${file%"${file#./*/}"}
echo mv -i -- "$file" "${parent}filtered_feature_bc_matrix/" ||
ret=$?
done
exit "$ret"' sh {} +
(如果高兴则删除echo
)。
尽管这没有 zmv 的保障。不过,该-i
选项应该有助于防止丢失数据。