【问题标题】:Bash copy all directory with content that matches a patternBash 复制所有内容与模式匹配的目录
【发布时间】:2015-12-03 00:12:18
【问题描述】:

是否有某种方法可以使用 bash 脚本复制包括内容在内的目录。例如

// Suppose there are many directory inside Test in c as,
   /media/test/
        -- en_US
                -- file1
                -- file 2 
        -- de_DE 
               -- file 1
               -- SUB-dir1
                  -- sub file 1
               -- file 2
               .....
               .....
        -- Test 1
              --  testfile1
              -- folder
                   --- more 1  
         ............

NoW i want to copy all the directories (including sub-directory and files)
to another location which matches the pattern.
--> for example , in above case I want the directories en_US and de_DE to be copied in another
location including sub-directories and files. 

到目前为止,我已经完成/找出:

1) 所需模式为 /b/w{2}_/w{2}/b

2) 我可以将所有目录列为 ,

$MYDIR="/media/test/"
DIRS=`ls -l $MYDIR | egrep '^d' | awk '{print $10}'`
for DIR in $DIRS
do
echo  ${DIR}
done

现在我需要帮助将它们组合在一起,以便脚本可以将与​​模式匹配的所有目录(包括子内容)复制到另一个位置。

提前致谢。

【问题讨论】:

  • 我只是不明白您打算如何将这两件事放在一起以给出合理的结果。但是,根据我对您要实现的目标的相当有限的解释,请查看命令 ls -aR1 ./directory_name,它将为您提供目录中内容的完整列表
  • bash 是一个 UNIX shell。 UNIX 没有folders,它有directories,UNIX 路径不是用反斜杠\ 分隔的,而是用正斜杠/ 分隔的。听起来您想要的 UNIX 命令只是 cp -r olddir newdir
  • @EdMorton:我确实改变了结构。好吧,如果该目录是已知的,那么将所有必需的目录复制到一个新位置可能会更容易。但情况是,可能有 1000 个具有 ex 结构的文件夹。 aa_bb 即 2 个字符,然后是下划线,然后是两个字符。我需要找到所有具有这种格式的目录并将其复制到新位置。
  • 有趣的是,您在问题中将文件夹更改为目录,然后继续描述 1000 个 文件夹 .... :-)。如果简单的cp -r 命令不是您需要的,请编辑您的问题以显示一些更具体的输入和输出示例。鉴于没有人提出任何其他建议,显然,鉴于您到目前为止告诉我们的内容,我们认为您需要的只是这些,所以如果这不是您需要的,您需要编辑您的问题以阐明您的要求。

标签: regex linux bash grep sh


【解决方案1】:

这是您 10 人的开胃菜:
您将不得不添加所需的额外检查和平衡,但它应该会给您一个良好的开端。

#!/bin/bash
# assumes $1 is source to search and $2 to destination to copy to
subdirs=`find $1 -name ??_?? -print`
echo $subdirs
for x in $subdirs
do
        echo $x
        cp -a $x $2
done

【讨论】:

  • 请注意,我已删除 for x in $subdirs 末尾的 :(冒号),因为这会导致通过在末尾添加冒号生成的任何列表的最后一行出现错误文件名
【解决方案2】:

要选择性地将整个目录结构复制到类似的目录结构,同时过滤内容,通常最好的办法是存档原始目录并取消存档。例如,使用 GNU Tar:

$ mkdir destdir
$ tar -c /media/test/{en_US,de_DE} | tar -C destdir -x --strip-components=1

在此示例中,/media/test 目录结构在destdir 下部分重新创建,不包括/media 前缀(感谢--strip-components=1)。

左侧tar 仅归档与我们指定的模式匹配的目录/路径。存档是在该命令的标准输出中生成的,该输出通过管道传送到右侧的解码 tar-C 告诉它切换到目标目录。它在那里提取文件,删除前导路径组件。

$ ls destdir
test
$ ls destdir/test
en_US de_DE

当然,使用cp -a 可以轻松处理您的特定示例测试用例:

$ mkdir destdir
$ cp -a /media/test/{en_US,de_DE} destdir

如果模式很复杂,涉及在源目录层次结构的更深和/或不同级别的多个子树材料选择,那么您需要更通用的方法,如果您希望在单个批处理命令中进行复制指定源模式。

【讨论】:

    【解决方案3】:

    请检查这是否是您想要的。它搜索格式为 xx_yy/ab_cd/&&_$$ (2char_2char) 的目录并将内容复制到新目录。

    usage : ./script.sh
    
    cat script.sh
    
    #!/bin/bash
    
    MYDIR="/media/test/"
    NEWDIRPATH="/media/test_new"
    DIRS=`ls -l $MYDIR | grep "^d" | awk '{print $9}'`
    for DIR in $DIRS
    do
            total_characters=`echo $DIR | wc -m`
            if [ $total_characters -eq 6 ]; then
                    has_underscore=`echo "$DIR" | grep "_"`
                    if [ "$has_underscore" != "" ]; then
                            echo "${DIR}"
                            start_string_count=`echo $DIR | awk -F '_' '{print $1}' | wc -m`
                            end_string_count=`echo $DIR | awk -F '_' '{print $2}' | wc -m`
                            echo "start_string_count => $start_string_count ; end_string_count => $end_string_count"
                            if [ $start_string_count -eq 3 ] && [ $end_string_count -eq 3 ]; then
                                    mkdir -p $NEWDIRPATH/"$DIR"_new
                                    cp -r $DIR $NEWDIRPATH/"$DIR"_new
                            fi
                    fi
            fi
    done
    

    【讨论】:

      【解决方案4】:

      我不确定您的环境,但我猜您尝试这样做:

      cp -r src_dir/??_?? dest_dir
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 2017-03-18
        • 2022-10-20
        • 1970-01-01
        • 2019-06-11
        • 1970-01-01
        相关资源
        最近更新 更多