파일을 이동하고 대상으로 추적하기 위한 별칭

파일을 이동하고 대상으로 추적하기 위한 별칭

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"; }

여기서는 이전 명령이 성공한 경우에만 두 번째 명령이 실행되도록 하기 때문에 링크 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이 댓글에 썼듯이,

대체 텍스트에 매개변수를 사용하는 메커니즘은 없습니다. 매개변수가 필요한 경우 쉘 함수를 사용해야 합니다(아래 함수 참조).

별칭은 어떻게 작동하나요?

명령줄에 다음 두 줄을 입력하면 어떤 일이 발생하는지 생각해 보겠습니다.

$ alias word1="echo example"

$ word1 word2 word3

첫 번째 명령을 실행한 후에는 명령 bash이 나올 때마다 word1해당 명령의 첫 번째 단어로 바꿔야 한다는 점을 기억하세요 echo example. 두 번째 명령을 보면 먼저 가능한 가장 어리석은(가장 간단한) 방법으로 대체를 수행합니다. 즉, 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를 넣습니다. 그렇지 않은 경우 두 번째 인수를 처음부터 맨 오른쪽까지 부분 문자열로 묶고 /그 안에 넣습니다.


[1] 조건 없이 이 작업을 수행하려고 dirname과 readlink를 함께 묶거나 항상 경로나 다른 해킹을 앞에 추가하는 등 많은 시간을 낭비했지만 ./항상 문제에 부딪혔습니다. of readlink) 또는 cding to 에서는 작동하지 않습니다 ... 또는 파일 이름에서는 작동하지 않습니다. 예. 누구든지 문자열 없이 이 작업을 수행할 수 있다면 제안에 열려 있습니다.

관련 정보