Псевдоним для перемещения файлов и слежения за ними к месту назначения

Только поставив альтернативу sed. Это напечатает последний столбец из строки, разделенной пробелами.

 sed 's/.*[[:space:]]\(.*\)$/\1/'

Я протестировал его для случаев, когда a.resolvers.level3.netявляется единственной строкой в ​​переменной $name, и она работает.

$ echo "$name"
1.2.2.4.in-addr.arpa domain name pointer a.resolvers.level3.net
$
$ echo "$name"|sed 's/.*[[:space:]]\(.*\)$/\1/'
a.resolvers.level3.net
$
$ name="a.resolvers.level3.net"
$ echo "$name"|sed 's/.*[[:space:]]\(.*\)$/\1/'
a.resolvers.level3.net
$
1
16.06.2017, 01:11
4 ответа

Псевдоним не поддерживает такие операнды, как $@, $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/

Псевдоним — это своего рода простая замена.

Псевдоним aa='command1;command2', при вызове как aa sometextравноcommand1;command2 sometext

Чтобы заставить это работать, вам нужно сделать это с помощью функции. Bash не поощряет использование псевдонимов и поощряет использование функций для таких заданий. Вы можете прикрепить эту функцию к вашему файлу профиля bash, и эта функция может быть вызвана по имени прямо из вашего терминала, как если бы вы делали это с любым псевдонимом:

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

Связывание команд mvи cdс &&здесь важно, так как &&гарантирует, что вторая команда cdбудет выполнена только в том случае, если предыдущая команда mvбыла успешной.

В качестве альтернативы, как уже было сказано в ссылке принятого ответа на ваш вопрос , вы можете сделать что-то вроде

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=
5
27.01.2020, 23:14

Как написал @Deathgrip в комментарии,

не существует механизма для использования аргументов в замещающем тексте. Если требуются аргументы, следует использовать функцию оболочки (см. ФУНКЦИИ ниже).

Как работают псевдонимы?

Давайте подумаем, что произойдет, если вы введете следующие две строки в командной строке:

$ alias word1="echo example"

$ word1 word2 word3

При выполнении первой команды bash помнит, что всякий раз, когда word1 является первым словом любой команды, он должен заменить его на echo example. Увидев вторую команду, он прежде всего выполняет подстановку самым тупым (самым простым) способом — из этого ввода создает команду echo example word2 word3. Поэтому он повторяет пример слово2 слово3.

Что происходит с вашим псевдонимом?

Когда он видит mfav one two, он просто оценивает mv $@ && cd $_ one two. Поскольку $@ пусто (попробуйте echo $@ в консоли), mv не работает. cd также не работает, так как получает больше аргументов, чем один.

Примечание: я слишком упростил запись, что псевдоним заменяет только первое слово. В случае нарушения этого правила см. мой другой ответ .

0
27.01.2020, 23:14

Все остальные ответы объясняют, почему псевдоним не работает, а ответ Джорджа Василиу дает альтернативную функцию, которая выполняет эту работу.

Однако я хотел развить этот ответ, чтобы сделать его более надежным. В настоящее время функция

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 в него. Если это не так, то мы подстроим второй аргумент от начала до самого правого / и cd в него.


[1] Я потратил неприлично много времени, пытаясь сделать это без условного обозначения, связывая вместе имя каталога и ссылку для чтения или просто всегда добавляя ./ перед путем или другими хаками, но у меня всегда была проблема. - либо это будет cd слишком далеко назад (в случае readlink), либо это не будет работать с cding на .. , или это не будет работать с именами файлов или... да. Если кто-то может сделать это без условного, я очень открыт для предложений.

0
27.01.2020, 23:14

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/

и заставляет вас думать, что это сработало!

1
27.01.2020, 23:14

Теги

Похожие вопросы