拡張子(zsh、macOS)に従ってファイルをディレクトリに移動します。

拡張子(zsh、macOS)に従ってファイルをディレクトリに移動します。

~/jpgすべてのファイルをすでに持っているディレクトリ構造(、、、~/pngなど~/mp3)に自動的に移動するスクリプトが必要です~/zip。これまで、これは私が望むものとほぼ正確に一致しています。

#!/bin/zsh
echo "Executing Script"
find . -iname '*.jpg' -exec gmv -i --target-directory=$HOME/jpg '{}' +
find . -iname '*.png' -exec gmv -i --target-directory=$HOME/png '{}' +

私はシェルスクリプトの経験がないので、これは私が一緒に編まれたものです。

単に連続した行に連続コマンドを実行することは、シェル用のスクリプトを作成する正しい方法ですか?最初にこれを試しましたが、mvエラー処理が必要で、エレガントではありませんでした。延長しようユーザーEvilSoupの回答はここにあります。

すでに述べたものに加えて、mv -iフラグも含めました。これにより、すでに存在する項目が上書きされません。(この部分は非常に重要です。)多分これは-nより良いかもしれません。

についてfindmv現在のディレクトリでのみ操作を実行したいです。、そして何らかの理由でfind制限する方法をよく理解していませんが、少し再帰的なようです。すべてのディレクトリでスクリプトを実行し、mv 現在の作業ディレクトリにあるファイルのみを含めたいと思います。find

zsh-on-macOS-の場合は+1特定紹介資料:シェルスクリプト。

ベストアンサー1

あなたは何も間違っていませんでした。スクリプトの作成を開始すると、最初のスクリプトはコマンドが順番にリストされたリストにすぎず、これは完全に正常です。

しかし、それ以上に進む方法を学ぶことを願っています。あなたの台本が悪いというわけではありませんが、比較してあなたの台本の代わりに私が書いているものを見せたいです。条件付き、ループ、および安全チェックを使用し、スクリプトが実行するアクションを確認できるように、複数のコメントを追加しました。

#!/usr/bin/env zsh

# announce that the script has started
echo "Running sorting script."

# the variable "$1" means the first argument to the script, i.e., if
# the script is named "mysorter.zsh" if you ran mysorter.zsh ~/tmp
# then $1 would be "~/tmp"
# I'm assigning that to the variable "argument"
argument="$1"

# if $argument is blank, I want the script to run in the present 
# directory; if not, I want to move to that directory first
# [[ -n "$argument" ]] means "$argument is not blank" (not length 0)
# for other conditions like -n, see 
# https://zsh.sourceforge.io/Doc/Release/Conditional-Expressions.html
if [[ -n "$argument" ]] ; then
    # [[ -d "$argument" ]] checks if "$argument" is a directory; if it's
    # not, the command is a mistake and the script should quit
    # the "!" means "not"
    if [[ ! -d "$argument" ]] ; then
        # echo prints text; the ">&2" means print to the standard error
        # stream, rather than regular output stream, because this is an
        # error message
        echo "$argument either does not exist or is not a directory" >&2
        # exit quits the script; the number indicates the error code; if
        # you write "exit 0" that means no error; but this is an error
        # so I give it a non-zero code
        exit 1
    fi
    # if we made it here, then "$argument" is indeed a folder, so I
    # move into it
    cd "$argument"
fi

# this is a loop that will be separately processed for all files in
# the active directory
for file in * ; do
    # I indent inside the loop to indicate better where the loop starts
    # and stops

    # first I check if "$file" is a folder/directory; if it is, 
    # I don't want to do anything; "continue" means cease this cycle
    # through the loop and move on to the next one
    if [[ -d "$file" ]] ; then
        continue
    fi

    # what I want to do next depends on the extension of "$file";
    # first I will determine what that is
    # the notatation "${file##*.}" means cut off everything prior to
    # the final . ; 
    # see https://zsh.sourceforge.io/Doc/Release/Expansion.html#Parameter-Expansion
    extension="${file##*.}"

    # i want to treat extensions like JPG and jpg alike, so I will make
    # the extension lowercase; see the same page above
    extension="${(L)extension}"

    # I want to move the file to a folder in $HOME named after the 
    # extension, i.e., $HOME/$extension; first I check if it doesn't
    # exist yet
    if [[ ! -d "$HOME/$extension" ]] ; then
        # since it doesn't exist, I will create it
        mkdir "$HOME/$extension"
    fi

    # by default we want the move target to have the same name
    # as the original file
    targetname="$file"
    # but I may need to add a number to it; see below
    num=0
    # now I want to check if there is already a file in there with
    # that name already, and keep changing the target filename
    # while there is
    while [[ -e "$HOME/$extension/$targetname" ]] ; do
        # a file with that name already exists; but I still want
        # to put the file there without overwriting the other one;
        # I will keep checking numbers to add to the name until I
        # find one for a file that doesn't exist yet
        
        # increase by one
        let num++
        
        # the new targetname is filename with the extension cut off, 
        # plus "-$num" plus the extension
        # e.g. "originalfilename-1.zip"
        targetname="${file%.*}-${num}.${extension}"
    done

    # we have now found a safe file name to use for the target, 
    # so we can move the file
    echo "Moving file $file to $HOME/$extension/$targetname"
    # here we try to move the file, but if it fails, we 
    # print an error and quit the script with an error
    if ! mv "$file" "$HOME/$extension/$targetname" ; then
        echo "Move command failed!" >&2
        exit 1
    fi
    
    # we're now done with this file and can move on to the next one
done
# done indicates the end of the loop
#
# if we got here everything was successful and quit with exit code 0
echo "All files successfully sorted."
exit 0

これは唯一の可能性についてのアイデアを提供することです。

スクリプトが完璧になるか心配しないでください。練習すればするほど良くなります。このスクリプトがあなたに適している場合は、あなたに適しています。

明らかにリンクをいくつか追加しました。https://zsh.sourceforge.ioこれはzshの詳細を学ぶための良い資料です。

学習しようとする必要があるので、Macに関連するものは追加しません。いいえ特に、独自のプラットフォームからオープンソースのプラットフォームに切り替えて実際に収容できる場合は、1つのプラットフォームに接続してください。Unixの哲学(私は説教しないようにしています。これは効果的ですか?)

おすすめ記事