Linux

在bash中使用if條件語句移動所有文件時跳過“特定文件副檔名文件”

  • December 18, 2020

我正在編寫一個bash 腳本,它將文件/目錄從現有目錄路徑移動到另一個目錄路徑。for loop但我在使用withif condition語句時無法跳過一些擴展文件。我的腳本執行沒有錯誤,但它不會跳過我指定的所需擴展文件,if condition而是移動所有文件和目錄。下面是我試圖創建的腳本。

請指導我在哪裡做錯了。

以下是我正在嘗試做的事情。

#!/bin/env bash

#moving home profile data to another location
echo "Moving Desktop Files"
path=/home/$USER/Desktop/*
for m in $path
do
     link=$(basename -s .lnk ${m})
     desktop=$(basename -s .desktop ${m})
     if [[  "${link}.lnk" == "${m}" ]] || [[ "${desktop}.desktop" == "${m}" ]]
     then
               echo "skipping link and desktop extension files"
               continue
     fi
mv -n "$m"  /home/$USER/CoreData/HOME/Desktop/

done

您正在以一種非常迂迴的方式匹配文件名後綴,並且您編寫循環的方式使其無法處理名稱中包含空格的文件。

if與您的陳述有關的主要問題$m是路徑名,包含目錄路徑元素,而$desktopand $link,如果解釋為文件名,則沒有目錄路徑元素。

更安全程式碼的建議:

#!/bin/bash

for name in "$HOME/Desktop"/*; do
   if [[ $name == *.lnk ]] || [[ $name == *.desktop ]]; then
       printf 'Skipping "%s"\n' "$name"
   else
       mv -n -- "$name" "$HOME/CoreData/HOME/Desktop"
   fi
done

==這使用(globbing)模式匹配與[[ ... ]]in bash

如果您真的想單獨進行名稱的通配並將它們保存在變數中,請為此使用數組:

names=( "$HOME/Desktop"/* )

for name in "${names[@]}"; do ... done

請注意,上面的引用很重要,以保持各個路徑名的完整性。

或者,使用以下case ... esac語句/bin/sh

#!/bin/sh

for name in "$HOME/Desktop"/*; do
   case $name in
       *.lnk|*.desktop)
           printf 'Skipping "%s"\n' "$name"
           ;;
       *)
           mv -n -- "$name" "$HOME/CoreData/HOME/Desktop"
   esac
done

同樣,您是否想單獨進行 globbing:

set -- "$HOME/Desktop"/*

for name do ... done

這使用位置參數而不是命名數組。shshell 不支持命名數組。

或者,使用rsync

rsync --archive --verbose \
   --exclude='*.lnk' \
   --exclude='*.desktop' \
   "$HOME/Desktop/" "$HOME/CoreData/HOME/Desktop"

"$HOME/Desktop"(如果你願意,然後刪除)

引用自:https://unix.stackexchange.com/questions/625084