2009-06-14 36 views
2

我收到以下消息的時候,比如應對dev的文件到主分支如何在bash/zsh/ksh中拷貝時創建目錄?

cp: /Users/Masi/gitHub/shells/zsh/dvorak: No such file or directory 
cp: /Users/Masi/gitHub/shells/zsh/dvorak2: No such file or directory 

我想詢問創建給定文件夾的時候,使得我最初的命令將被運行,如果我的回答是的問題。

我的僞代碼嘗試當我嘗試將文件複製到不存在一個目錄

if no such a directory exists, then asks users about to create it: 
    if yes, then mkdir directory AND run the initial command again 
    else do noting 

問題

  1. 要更改警告消息:哪個文件控制「沒有這樣的文件或目錄」 - 命令?
  2. 在初始命令中抓取路徑AND mkidr沒有文件的路徑:如何在初始命令中抓取路徑?
  3. 用您所選擇的語言如AWK從末尾刮掉:當/是字段分隔符時,如何刪除路徑中的最後一個匹配? 我不確定如何從AWK的末尾開始刮字母。
+0

也許這個問題的一個更好的標題就像「我怎樣才能創建在zsh複製過程中的目錄?」 – 2009-06-18 20:15:38

回答

2

這是我寫的函數,它可以在zsh,bash或ksh中使用。

注意:它已啓用調試(它會迴應它將運行的命令,而不是執行它們)。如果你註釋掉那條線,它會實際運行它們。

注意事項它尚未經過徹底測試。

要使用它,請將此腳本放入一個名爲cpmd的文件/usr/local/bin(或路徑中的其他位置)。要激活它,在shell提示下鍵入以下命令(或者把它添加到你的啓動腳本 - 對於bash這將是~/.bashrc):

source cpmd 

然後你就可以使用這樣的命令複製文件:

cpmd carparts /home/dave/Documents/nonexistent/newdir/ 

既不存在目錄「不存在」或「newdir」。兩個目錄都被創建,然後名爲「carparts」的文件被複制到「newdir」。

如果不包括斜線末(「/」),最後一部分被視爲一個文件名和任何不存在的目錄創建之前:

cpmd supplies /home/dave/Documents/anothernew/consumables 

目錄「另一個新」被創建,然後「耗材」被新的文件名「耗材」複製。

如果目標中的所有目錄已存在,則cpmd的行爲與常規的cp命令相似。

function cpmd { 
    # copies files and makes intermediate dest. directories if they don't exist 
    # for bash, ksh or zsh 
    # by Dennis Williamson - 2009-06-14 
    # http://stackoverflow.com/questions/993266/unable-to-make-nosuchdirectory-message-useful-in-zsh 

    # WARNING: no validation is performed on $1 and $2 

    # all cp commands below are hardcoded with -i (interactive) to prevent overwriting 

    if [[ -n $KSH_VERSION ]] 
    then 
     alias local=typeset 
     local func="$0" 
     local lastchar="${2: -1}" 
     readcmd() { read "$2?$1"; } 
    elif [[ -n $ZSH_VERSION ]] 
    then 
     local func="$0" 
     # the following two lines are split up instead of doing "${2[-1]}" 
     # to keep ksh from complaining when the function is loaded 
     local dest="$2" 
     local lastchar="${dest[-1]}" 
     readcmd() { read "$2?$1"; } 
    elif [[ -n $BASH_VERSION ]] 
    then 
    local func="$FUNCNAME" 
     local lastchar="${2:(-1)}" 
     readcmd() { read -p "$1" $2; } 
    else 
     echo "cpmd has only been tested in bash, ksh and zsh." >&2 
     return 1 
    fi 

    local DEBUG='echo' # COMMENT THIS OUT to make this function actually work 

    if [[ ${#@} != 2 ]] 
    then 
     echo "$func: invalid number of parameters 
Usage: 
    $func source destination 

    where 'destination' can include nonexistent directories (which will 
    be created). You must end 'destination' with a/in order for it to 
    specify only directories. Without the final slash, the 'source' will 
    be copied with a new name (the last portion of 'destination'). If you 
    are copying multiple files and 'destination' is not a directory, the 
    copy will fail." >&2 
     return 1 
    fi 

    local dir=$(dirname "$2") 
    local response 
    local nl=$'\n' 

    # destination ($2) is presumed to be in one of the following formats: 
    # .../existdir    test 1 (-d "$2") 
    # .../existdir/existfile test 2 (-f "$2") 
    # .../existdir/newfile  test 3 (-d "$dir" && $lastchar != '/') 
    # .../existdir/newdir/  (else) 
    # .../newdir/newdir/  (else) 
    # .../newdir/newfile  (else) 

    if [[ -d "$2" || -f "$2" || (-d "$dir" && $lastchar != '/') ]] 
    then 
     $DEBUG cp -i "$1" "$2" 
    else 
     if [[ $lastchar == '/' ]] 
     then 
      dir="$2" 
     fi 
     local prompt="$func: The destination directory...${nl} ${dir}${nl}...does not exist. Create? (y/n): " 
     while [[ -z $response ]] 
     do 
      readcmd "$prompt" response 
      case $response in 
       y|Y) response="Y" ;; 
       n|N) ;; 
       *) response= 
        prompt="$func: Invalid response.${nl} Create destination directory? (y/n): ";; 
      esac 
     done 
     if [[ $response == "Y" ]] 
     then 
      $DEBUG mkdir -p "$dir" && $DEBUG cp -i "$1" "$2" 
     else 
      echo "$func: Cancelled." >&2 
     fi 
    fi 
} 
+0

@Dennis:我無法在OS/X中運行你的代碼。我把它放到/ usr/local/cpmd /和我的PATH中。當我將文件複製到不存在的目錄時,它不會被激活。 – 2009-06-15 16:56:27

1

該錯誤消息來自cp命令,而不是zsh。如果你想改進輸出,你將不得不編寫截斷和檢查路徑的邏輯,並檢查它是否存在。

有一些命令可以幫助您理解basename(1)和dirname(1)。