如何将文件从X sub_dir移到Y sub_dir [英] How to move files from X sub_dir to Y sub_dir

查看:130
本文介绍了如何将文件从X sub_dir移到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兼容的外壳(如bashzsh)一起使用.

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 to mv.

更强大的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/nullmv在没有匹配项的情况下静默失败,但这是不可取的,因为它可以掩盖真正的错误情况.
      • 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 let mv 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆