首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列出目录中的文件,并将其复制-替换到Linux的另一个目录中

列出目录中的文件,并将其复制-替换到Linux的另一个目录中
EN

Stack Overflow用户
提问于 2020-03-05 23:22:38
回答 3查看 76关注 0票数 0

我们有两个目录,如下所述,每当我们在Directory-1中获得新文件时,只有它们应该被复制并替换到Directory-2中。如何在Linux脚本中实现这一点。文件名保持不变,但版本会有所不同。

代码语言:javascript
复制
Directory-1:
FileOne_2.0.0.txt
FileTwo_3.0.0.txt

Directory-2:
FileOne_1.0.0.txt
FileTwo_2.0.0.txt
FileThree_3.0.0.txt
FileFive_5.0.0.txt
EN

回答 3

Stack Overflow用户

发布于 2020-03-06 04:11:39

尝试此代码(在您信任您的真实目录和文件之前,在测试设置上):

代码语言:javascript
复制
#! /bin/bash -p

shopt -s extglob    # Enable extended globbing ( +([0-9]) ... )
shopt -s nullglob   # Globs that match nothing expand to nothing
shopt -s dotglob    # Globs match files with names starting with '.'

srcdir='Directory-1'
destdir='Directory-2'

# A(n extended) glob pattern to match a version string (e.g. '543.21.0')
readonly kVERGLOB='+([0-9]).+([0-9]).+([0-9])'

# shellcheck disable=SC2231 # (Bad warning re. unquoted ${kVERGLOB})
for srcpath in "$srcdir"/*_${kVERGLOB}.txt; do
    srcfile=${srcpath##*/}  # E.g. 'FileOne_2.0.0.txt'
    srcbase=${srcfile%_*}   # E.g. 'FileOne'

    # Set and check the path that the file will be moved to
    destpath=$destdir/$srcfile
    if [[ -e $destpath ]]; then
        printf "Warning: '%s' already exists.  Skipping '%s'.\\n" \
                "$destpath" "$srcpath" >&2
        continue
    fi

    # Make a list of the old versions of the file
    # shellcheck disable=SC2206 # (Bad warning re. unquoted ${kVERGLOB})
    old_destpaths=( "$destdir/$srcbase"_${kVERGLOB}.txt )
    # TODO: Add checks that the number of old files (${#old_destpaths[*]})
    #       is what is expected (exactly one?)

    # Move the file
    if mv -i -- "$srcpath" "$destpath"; then
        printf "Moved '%s' to '%s'\\n" "$srcpath" "$destpath" >&2
    else
        printf "Warning: Failed to move '%s' to '%s'.  Skipping '%s'.\\n" \
                "$srcpath" "$destpath" "$srcpath" >&2
        continue
    fi

    # Remove the old version(s) of the file (if any)
    for oldpath in "${old_destpaths[@]}"; do
        if rm -- "$oldpath"; then
            printf "Removed  '%s'\\n" "$oldpath" >&2
        else
            printf "Warning: Failed to remove '%s'.\\n" "$oldpath" >&2
        fi
    done
done

  • 代码是Shellcheck-clean。由于未加引号的展开是必需的,因此使用了两个外壳检查抑制注释,将here.
  • srcdirdestdir设置为常量。您可能希望从命令行参数中获取它们,或者将它们设置为不同的常量值。
  • 可以通过删除检查来缩短代码。然而,移动和删除是破坏性的操作,如果它们做得不正确,会造成很大的损害。如果它是我自己的数据,我会添加更多的检查。
  • 有关代码中使用的“扩展全局扫描”的解释,请参阅glob - Greg's Wiki
  • 有关代码和${srcfile%_*}.
  • mv -i的解释,请参阅
  • ,它用作防止覆盖现有文件的双重保护。
  • 所有外部命令都是使用<代码>d23调用的,以显式结束选项,如果它们与以-.
  • Make开头的路径一起使用,请确保您理解代码,并在真正使用它之前对其进行非常仔细的测试。
票数 1
EN

Stack Overflow用户

发布于 2020-03-05 23:53:40

代码语言:javascript
复制
source_dir=./files/0
dest_dir=./files/1/
for file in $source_dir/*
do
  echo $file
  echo "processing"
  if [[ "1" == "1" ]]; then
    mv $file $dest_dir
  fi
done

Where processing和1 == 1就是你的“预检”(你还没有告诉我们)

票数 0
EN

Stack Overflow用户

发布于 2020-03-06 09:14:16

如果您的coreutils sort高于或等于v7.0 (2008-10-5),之后sort命令支持版本选项( -V -sort),您是否会尝试:

代码语言:javascript
复制
declare -A base2ver base2file

# compare versions
# returns 0 if $1 equals to $2
#         1 if $1 is newer than $2
#        -1 if $1 is older than $2
vercomp() {
    if [[ $1 = $2 ]]; then
        echo 0
    else
        newer=$(echo -e "$1\n$2" | sort -Vr | head -n 1)
        if [[ $newer = $1 ]]; then
            echo 1
        else
            echo -1
        fi
    fi
}

for f in Directory-1/*.txt; do
    basename=${f##*/}
    version=${basename##*_}
    version=${version%.txt}       # version number such as "2.0.0"
    basename=${basename%_*}       # basename such as "FileOne"
    base2ver[$basename]=$version  # associates basename with version number
    base2file[$basename]=$f       # associates basename with full filename
done

for f in Directory-2/*.txt; do
    basename=${f##*/}
    version=${basename##*_}
    version=${version%.txt}
    basename=${basename%_*}

    if [[ -n ${base2ver[$basename]} ]] && (( $(vercomp "${base2ver[$basename]}" "$version") > 0 )); then
#       echo "${base2file[$basename]} is newer than $f"
        rm -- "$f"
        cp -p -- "${base2file[$basename]}" Directory-2
    fi
done
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60548705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档