簡體   English   中英

列出目錄中的文件並將它們復制替換到 Linux 中的另一個目錄中

[英]List the files in Directory and Copy-Replace them into another Directory in Linux

我正在嘗試自動執行以下操作:請提供任何幫助。
如下所述,我們有 2 個目錄,每當我們在 Directory-1 中獲得新文件時,只需將它們復制並替換到 Directory-2 中即可。 如何在 Linux 腳本中實現這一點。 文件名保持不變,但版本會有所不同。

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

試試這個代碼(在你信任你的真實目錄和文件之前的測試設置):

#! /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。 使用了兩個 Shellcheck 抑制注釋,因為這里需要不加引號的擴展。
  • srcdirdestdir設置為常量值。 您可能希望從命令行參數中獲取它們,或者將它們設置為不同的常量值。
  • 可以通過刪除檢查來縮短代碼。 但是,移動和移除是破壞性的操作,如果操作不當,可能會造成很大的傷害。 如果是我自己的數據,我會添加更多檢查。
  • 有關代碼中使用的“擴展通配符”的解釋,請參閱glob - Greg 的 Wiki
  • 有關${srcpath##*/}${srcfile%_*}的解釋,請參閱參數擴展 [Bash Hackers Wiki]
  • mv -i用作防止覆蓋現有文件的雙重保護。
  • 所有外部命令都使用--調用以明確結束選項,以防它們與以-開頭的路徑一起使用。
  • 在真正使用它之前,請確保您理解代碼並非常仔細地測試它。
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

處理和 1 == 1 的位置是您的“預檢”(您沒有告訴我們)

如果您的coreutils sort更新或等於 v7.0 (2008-10-5) 之后sort命令支持-V選項(版本排序),請嘗試:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM