Linux
在bash中使用if條件語句移動所有文件時跳過“特定文件副檔名文件”
我正在編寫一個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
是路徑名,包含目錄路徑元素,而$desktop
and$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)模式匹配與[[ ... ]]
inbash
。如果您真的想單獨進行名稱的通配並將它們保存在變數中,請為此使用數組:
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
這使用位置參數而不是命名數組。
sh
shell 不支持命名數組。或者,使用
rsync
:rsync --archive --verbose \ --exclude='*.lnk' \ --exclude='*.desktop' \ "$HOME/Desktop/" "$HOME/CoreData/HOME/Desktop"
"$HOME/Desktop"
(如果你願意,然後刪除)