ファイルを移動してターゲットに追跡するためのエイリアス

ファイルを移動してターゲットに追跡するためのエイリアス

cdファイルを移動してターゲットディレクトリに従うことができるスクリプト(より正確にはエイリアス)を作成しようとしています。これ受け入れられた回答この問題には、次のコードを使用することをお勧めします。

mvf() { mv "$@" && goto "$_"; }

ここではgotoand のより安全なバリアントで、最後のコマンドに渡された最後の引数です。cd$_

私の派生実装は次のとおりです。

alias mvaf="mv $@ && cd $_"

$@すべてのパラメータを使用して名前でファイルを移動するのを防ぐために、引用符はありません。最初にこれを変えようとしましたが、スクリプトも失敗しました。上記の実装を呼び出すと、mvaf test1 test2 ..「mv:欠落ファイルオペランド」が発生します(翻訳済み)。

デバッグ時に使用しようとしませんでしたが、cd実際にはalias mvaf="mv $@ "デフォルトで名前が変更され、ファイルがmv移動されました。

これでmv、最初の実装でオペランドが欠落している理由とこれが&&

答え1

エイリアスは、$@、$1、$2 などのオペランドをサポートしません。

注文

alias mvaf="mv $@ && cd $_"

エイリアスが期待どおりに認識されないmv ' ' && cd $_ため、同じです。$@

これは次のように簡単に証明できます。

$ alias mvaf='echo "Part 1:" $@ && echo "Part 2: " $_'
$ mvaf file66 /tmp/
Part 1:
Part 2:  Part 1: file66 /tmp/
#Part 2 includes the previous executed command (echo "Part 1:" $@) & the text sent after alias name 

$ alias mvaf='echo "Part 1:" $@;echo "Part 2: "'
$ mvaf file66 /tmp/
Part 1:
Part 2:  file66 /tmp/

一方、これはうまくいきますが、$ @のため動作しません。

$ alias mvaf='echo "mv $@"'
$ mvaf file66 /tmp/
mv  file66 /tmp/

$ alias mvaf='echo "mv"'
$ mvaf file66 /tmp/
mv file66 /tmp/

一般に、エイリアスは単純な置換です。

Alias aa='command1;command2'aa sometext同じように呼び出される場合command1;command2 sometext

これを行うには、関数を使用する必要があります。 Bashはエイリアスの使用を推奨しておらず、この種の操作を実行するために関数を使用することをお勧めします。この関数をbash構成ファイルに貼り付けて、エイリアスのように端末から直接名前で呼び出すことができます。

mvcd() { mv "$1" "$2" && cd "$2"; }

ここでは、前のコマンドが成功した場合にのみ2番目のコマンドを実行するため、リンクmvcdコマンドが&&重要です。&&cdmv

またはすでに提案したようにあなたの質問に許可された回答へのリンクから、あなたは次のことができます

mvf() { mv "$@" && goto "$_"; }
goto() { [ -d "$1" ] && cd "$1" || cd "$(dirname "$1")"; }

bashスプレーに注意してください。この機能を正しく機能させるには、移動中のファイルまたは転送されるファイルのディレクトリ名にスペースが含まれている場合は、その機能を呼び出すときに二重引用符を入れる必要があります。

$ mvcd() { echo "1=$1";echo "2=$2";echo "3=$3";echo "4=$4"; }

$ mvcd spaced file1 /spaced directory/
1=spaced
2=file1
3=/spaced
4=directory/

$ mvcd "spaced file1" "/spaced directory/"
1=spaced file1
2=/spaced directory/
3=
4=

答え2

alias$@または$_(または)は特別とは見なされず、$anythingそのままシェルに渡されます。

したがって、オリジナルは次のようになります。

alias mvaf="mv $@ && cd $_"

意味は次のとおりです

mvaf f dst/

になる:

mv $@ && cd $_ f dat/

$@とは$_定義される可能性がないため、シェルはこれを次のように解釈します。

mv && cd f dat/

したがって、mv引数なしで呼び出すと、「ファイルオペランドの欠落」エラーが発生します。

次のようにオーバーライドすると:

alias mvaf="mv $@ "

そして、以下を実行します。

mvaf f dst/

それは次のようになります:

mv $@ f dst/

前と同様に、次のように単純化されます。

mv f dst/

そしてそれがうまくいったと思うように欺く!

答え3

@Deathgripがコメントに書いたように、

代替テキストにパラメータを使用するメカニズムはありません。パラメータが必要な場合は、シェル関数を使用する必要があります(以下の関数を参照)。

エイリアスはどのように機能しますか?

コマンドラインに次の2行を入力すると、何が起こるのかを考えてみましょう。

$ alias word1="echo example"

$ word1 word2 word3

最初のコマンドを実行したら、コマンドが出るbashたびにword1そのコマンドの最初の単語に置き換える必要があることに注意してくださいecho example。 2番目のコマンドを見ると、最初に可能な最も愚かな(最も簡単な)方法で置き換えが行われます。つまり、echo example word2 word3その入力からコマンドを生成します。だから答えがありましたexample word2 word3

今、あなたのエイリアスはどうなりますか?

それを見ればmfav one two評価するmv $@ && cd $_ one two。空で失敗します$@echo $@コンソールで試してください)。また、複数の引数を受け取ったため失敗します。mvcd

注:私の記事は過度に単純化され、エイリアスは最初の単語のみを置き換えます。この規則に違反した場合、私の他の答えを見る

答え4

他のすべての答えはエイリアスが機能しない理由を説明し、George Vasiliuの答えはタスクを実行する代替機能を提供します。

しかし、私はこの答えに基づいてより強力にしたいと思います。現在、この機能は

mvcd() { mv "$1" "$2" && cd "$2"; }

ターゲットがファイルの場合、効果はありません。この問題を解決するために、bash変数の部分文字列表記を使用できます。

mvcd() { mv "$1" "$2" && [[ -d $2 ]] && cd $2 || cd ${2%/*}; }

ここで何が起こっているのかを確認するために、より読みやすい形式で書いてみましょう。

mvcd () {
    mv "$1" "$2";     # Do the move
    if [[ -d $2 ]]    # Check if arg $2 is a dir
    then
        cd $2;        # if it is, cd into it
    else
        cd ${2%/*};   # else remove the filename and cd
    fi;
}

宛先がディレクトリ[1]であることを確認してください。その場合は、ディレクトリにCDを挿入します。それ以外の場合は、2番目の引数を最初から右端まで部分文字列で囲み、/その中に入れます。


[1]条件なしでこれを実行しようとして、dirnameとreadlinkを一緒に結び付けたり、常にパスや他のハッキングを前に追加するなど、多くの時間を無駄にしましたが、./常に問題に遭遇しました。 of readlink)またはcding toでは機能しません..。またはファイル名では機能しません。はい。誰もが文字列なしでこれを行うことができる場合は、提案で開いています。

関連情報