【问题标题】:How do I copy directory structure containing placeholders如何复制包含占位符的目录结构
【发布时间】:2016-05-07 06:12:34
【问题描述】:

我有这样的情况,模板目录 - 包含文件和链接 (!) - 需要递归复制到目标目录,保留所有属性。模板目录包含任意数量的占位符 (__NOTATION__),需要将其重命名为特定值。

例如模板如下所示:

./template/__PLACEHOLDER__/name/__PLACEHOLDER__/prog/prefix___FILENAME___blah.txt

目的地变成这样:

./destination/project1/name/project1/prog/prefix_customer_blah.txt

到目前为止我尝试的是这样的:

# first create dest directory structure
while read line; do
  dest="$(echo "$line" | sed -e 's#__PLACEHOLDER__#project1#g' -e 's#__FILENAME__#customer#g' -e 's#template#destination#')"
  if ! [ -d "$dest" ]; then
    mkdir -p "$dest"
  fi
done < <(find ./template -type d)

# now copy files
while read line; do
  dest="$(echo "$line" | sed -e 's#__PLACEHOLDER__#project1#g' -e 's#__FILENAME__#customer#g' -e 's#template#destination#')"
  cp -a "$line" "$dest"
done < <(find ./template -type f)

但是,我意识到,如果我想处理权限和链接,这将是无穷无尽的并且非常复杂。是否有更好的方法将 __PLACEHOLDER__ 替换为“值”,例如使用 cpfindrsync

【问题讨论】:

    标签: bash shell scripting rsync placeholder


    【解决方案1】:

    我怀疑你的脚本已经可以做你想做的事了,只要你替换

    find ./template -type f
    

    find ./template ! -type d
    

    否则,显而易见的解决方案是使用cp -a 制作模板的“存档”副本,包括所有链接、权限等,然后然后重命名副本中的占位符。

    cp -a ./template ./destination
    while read path; do
      dir=`dirname "$path"`
      file=`basename "$path"`
      mv -v "$path" "$dir/${file//__PLACEHOLDER__/project1}"
    done < <(`find ./destination -depth -name '*__PLACEHOLDER__*'`)
    

    请注意,您需要使用-depth,否则重命名目录中的文件会中断。

    如果在创建目录树时使用已更改的名称对您非常重要(即,您决不能在目标中看到占位符),那么我建议仅使用中间位置。

    【讨论】:

    • 我也很喜欢这个解决方案,这对我来说实际上是可行的。但我注意到我必须将目录从“左到右”移动。因为例如 mv ./template/__PLACEHOLDER__/name/__PLACEHOLDER__/prog/prefix___FILENAME___blah.txt ./destination/project1/name/project1/prog/prefix_customer_blah.txt 会导致“没有这样的文件或目录”错误。
    • 这就是-depth 的意义所在。
    • 确实如此。谢谢!会尝试回来。
    【解决方案2】:

    使用 rsync 进行第一次复制,保留所有属性和链接等。 然后更改目标文件名中的占位符字符串:

    #!/bin/bash
    
    TEMPL="$PWD/template" # somewhere else
    
    DEST="$PWD/dest"      # wherever it is
    
    mkdir "$DEST"
    (cd "$TEMPL"; rsync -Hra . "$DEST")   # 
    MyRen=$(mktemp)
    trap "rm -f $MyRen" 0 1 2 3 13 15
    
    cat >$MyRen <<'EOF'
    #!/bin/bash
    fn="$1"
    newfn="$(echo "$fn" |  sed -e 's#__PLACEHOLDER__#project1#g' -e s#__FILENAME__#customer#g' -e 's#template#destination#')"
    test "$fn" != "$newfn" &&  mv "$fn" "$newfn"
    EOF
    
    chmod +x $MyRen
    
    find "$DEST" -depth -execdir $MyRen {} \;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      相关资源
      最近更新 更多