如何将文件从X sub_dir移到Y sub_dir [英] How to move files from X sub_dir to Y sub_dir
问题描述
我有主DIR X,在其中有许多子目录,例如A,B,C,D.我有主DIR Y,在其中有许多子目录,它们的名称与X主目录的子目录相同,例如A,B,C,D.
I have main DIR X and inside this I have many sub directories like A,B,C,D. I have main DIR Y and inside this i have many sub directories with same name as X main directory sub directories like A,B,C,D.
现在我只需要将文件从X主目录子目录移动到Y主目录子目录.
Now I need to MOVE only files from X main dir sub directories to Y main directory sub directory.
例如:
在主目录X内,子目录A有100个文件
Inside main directory X ,sub directory A has 100 files
B有1个文件
C有5个文件
D有50个文件...
and D has 50 files...
我的光标应该在主目录DIR X上,从那里我需要将所有子目录文件移动到Y主目录中相同的命名子目录(A,B,C,D).
my cursor should be at main DIR X , from there I need to MOVE all the sub directory files to same named sub directories(A,B,C,D) which is there inside Y main directory.
我该如何在SHELL SCRIPTING(KSH)或UNIX中执行此操作?
how can I do this in SHELL SCRIPTING(KSH) or unix??
推荐答案
注意:从根本上进行了修订,以提供一个更简单的解决方案.底部是单线(较复杂).
一个符合POSIX的解决方案:
#!/bin/sh
# Specify source and target directories (example values)
dirFrom='/tmp/from'
dirTo='/tmp/to'
# Use globbing to find all subdirectories - note the trailing '/'
# to ensure that only directories match.
for subdir in "$dirFrom"/*/; do
# Extract the mere name.
# Note that using ${subdir##*/} is NOT an option here, because $subdir ends in '/'.
name=$(basename -- "$subdir")
# Make sure a subdirectory of the same
# name exists in the target dir.
mkdir -p "$dirTo/$name"
# Move all items in the source subdir. to the analogous target subdir.
mv "$subdir"* "$dirTo/$name/"
done
因此,上述内容也将与ksh
以及其他与POSIX兼容的外壳(如bash
和zsh
)一起使用.
The above will therefore work with ksh
as well, and also other POSIX-compatible shells such as bash
and zsh
.
此解决方案有两个潜在问题:
- 隐藏的项目(名称以
.
开头的项目)被忽略. - 如果没有子目录,脚本将中断.或其中任何一个为 empty ,因为-保留了诸如
*
之类的不匹配任何内容的通配模式,从而导致不存在的路径被传递到mv
.
- Hidden items (those whose name starts with a
.
) are ignored. - The script will break, if there are no subdirs. or if any of them is empty, because a globbing pattern such as
*
that does not match anything is left as-is, resulting in non-existent paths being passed tomv
.
更强大的Bash版本
Bash-与ksh
不同,不幸的是-具有选项可以解决两个问题:
Bash - unlike ksh
, unfortunately - has options that address both issues:
-
shopt -s dotglob
导致在执行globbing时包含隐藏的项目. -
shopt -s nullglob
导致不匹配任何内容的模式扩展为 empty 字符串.
shopt -s dotglob
causes hidden items to be included when globbing is performed.shopt -s nullglob
causes patterns that don't match anything to expand to the empty string.
#!/usr/bin/env bash
# Specify source and target directories (example values)
dirFrom='/tmp/from'
dirTo='/tmp/to'
shopt -s dotglob # include hidden items when matching `*`
shopt -s nullglob # expand patterns that don't match anything to the emtpy string
# Use globbing to find all subdirectories - note the trailing '/'
# to ensure that only directories match.
for subdir in "$dirFrom"/*/; do
# Extract the mere name.
# Note that using ${subdir##*/} is NOT an option here, because $subdir ends in '/'.
name=$(basename -- "$subdir")
# Make sure a subdirectory of the same
# name exists in the target dir.
mkdir -p "$dirTo/$name"
# Collect the paths of the items in the subdir. in
# an array, so we can test up front whether anything matched.
itms=( "$subdir"* )
# Move all items in the source subdir. to the analogous target subdir,
# but only if the subdir. contains at least 1 item.
[[ ${#itms[@]} -gt 0 ]] && mv "${itms[@]}" "$dirTo/$name/"
done
- 请注意,仅凭
shopt -s nullglob
还是不够的-我们仍然必须首先在数组中收集全局匹配,因此我们可以确定是否有任何匹配项.- 虽然我们可以只使用
2>/dev/null
让mv
在没有匹配项的情况下静默失败,但这是不可取的,因为它可以掩盖真正的错误情况. - Note how
shopt -s nullglob
by itself was not enough - we still had to collect globbing matches in an array first, so we could determine if anything matched.- While we could instead just use
2>/dev/null
to letmv
fail silently if there are no matches, this is not advisable, because it could mask true error conditions.
如果您对单线感兴趣,请参阅以下基于
find
的命令;但是,它们非常复杂.If you're interested in one-liners, here are
find
-based commands; they are, however, quite complex.# Note: Both solutions below ignore symlinks to directories as subdirectories. # [POSIX-compliant] Excluding hidden items. # Note how `\! -name '.*'` is explicitly added to the `find` command to ensure that no hidden subdirs. are matched, so as to # to match the shell globbing behavior of excluding hidden items. find "$dirFrom" -mindepth 1 -maxdepth 1 -type d \! -name '.*' -exec sh -c \ 'f=$1 t=$2/${1##*/}; set -- "$f"/*; [ -e "$1" ] && mkdir -p "$t" && mv "$@" "$t"' \ - {} "$dirTo" \; # [Bash] Including hidden items. find "$dirFrom" -mindepth 1 -maxdepth 1 -type d -exec bash -O dotglob -c \ 'f=$1 t=$2/${1##*/}; set -- "$f"/*; [[ -e $1 ]] && mkdir -p "$t" && mv "$@" "$t"' \ - {} "$dirTo" \;
这篇关于如何将文件从X sub_dir移到Y sub_dir的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- While we could instead just use
- 虽然我们可以只使用