{1,2,3}
— эторасширение фигурной скобки ,он распространяется на перечисленные слова независимо от их значения.
[...]
— это группа символов, используемая врасширении имени файла(или подстановочном знаке или подстановочном знаке )аналогично звездочке *
и вопросительному знаку ?
. Он соответствует любому отдельному символу, указанному внутри, или символам, которые являются членами именованных групп, таких как [:digit:]
, если они перечислены. По умолчанию большинство оболочек оставляют подстановочный знак как -, если нет файлов, соответствующих ему.
(Обратите внимание, что вы не можете превратить подстановочный знак/шаблон в набор строк, которым он будет соответствовать. Звездочка может соответствовать любой строке любой длины, поэтому расширение любого шаблона, содержащего ее, приведет к бесконечному списку строк.)
Так:
$ bash -c 'echo [[:digit:]]' # bash leaves it as-is
[[:digit:]]
$ zsh -c 'echo [[:digit:]]' # zsh by default complains if no match
zsh:1: no matches found: [[:digit:]]
$ touch 1 3 d i g t
$ bash -c 'echo [[:digit:]]' # now there are two matches
1 3 # note that d, i, g and t do NOT match
Но все же:
$ bash -c 'echo {1,2,3}'
1 2 3
Обе они расширяются оболочкой , не имеет значения, какую команду вы выполняете: ls
, echo
или rm
. Также обратите внимание, что если любой из них указан в кавычках, они не будут расширены:
$ bash -c 'echo "[[:digit:]]"' # even though matching files still exist
[[:digit:]]
$ bash -c 'echo "{1,2,3}"'
{1,2,3}
В некоторых оболочках, напр. ksh
и zsh
, выполнение cd word1 word2
приведет к изменению каталога, указанного путем изменения первого вхождения word1
в пути к текущему каталогу на word2
.
Например, в оболочке zsh
:
$ pwd
/usr/local/sbin
$ cd sbin bin
/usr/local/bin
$
В других оболочках, поддерживающих нестандартную -подстановку параметров ${variable/pattern/replacement}
, первоначально найденную в ksh93
, вы можете использовать ${PWD/word1/word2}
для создания пути к каталогу, который будет изменен на:
$ pwd
/usr/local/sbin
$ cd "${PWD/sbin/bin}"
$ pwd
/usr/local/bin
В этих оболочках (bash
, например ), можно даже создать свою собственную наивную cd
функцию для обработки двух аргументов так, как это делают ksh
и zsh
, вот так:
cd () {
if [ "$#" -eq 2 ] && [[ $1 != -* ]]; then
command cd -- "${PWD/$1/$2}" &&
printf 'New wd: %s\n' "$PWD"
else
command cd "$@"
fi
}
[ "$#" -eq 2 ]
определяет, когда должно запускаться специальное cd
поведение (, когда имеется ровно два аргумента командной строки ), но мы проверяем с [[ $1 != -* ]]
на , а не запускаем особое поведение, если вы используете опцию с cd
. Использование command cd
вместо cd
внутри функции позволяет избежать рекурсивного вызова функции.
Проверяем, что вbash
:
$ cd /usr/local/sbin
$ cd sbin bin
New wd: /usr/local/bin
$ cd local ''
New wd: /usr/bin
$ cd bin sbin
New wd: /usr/sbin
$ cd sbin local/sbin
New wd: /usr/local/sbin
$ cd '*/' /
New wd: /sbin
Обратите внимание, что последняя команда заменяется шаблоном, соответствующим последнему /
; шаблон должен быть указан.Чтобы запретить шаблоны и всегда обрабатывать первый аргумент как слово, используйте command cd "${PWD/"$1"/$2}"
в функции (обратите внимание на кавычки$1
).
Чтобы дополнительно принудительно заменить только полное имя каталога, используйте command cd "${PWD/"/$1/"/"/$2/"}"
. Искусственная вставка /
до и после обоих аргументов позволит избежать совпадения подстрок имен каталогов, но сделает это несовместимым с тем, как это работает в zsh
и ksh
, и больше не позволит вам делать замены в последней части. пути к каталогу, так как в конце (нет /
, вы можете обеспечить только определенный уровень удержания руки -до того, как дополнительная «помощь» станет помехой ).
Это заставит cd foo bar
работать с примером, который находится в вопросе. В противном случае вам пришлось бы следить за тем, чтобы foo
в foobar
не совпадало каким-либо другим образом, например, с cd foo/ bar/
.
Это просто.
cd "$( echo "$PWD" | sed -e 's%/foo/%/bar/%' )"
sed
использует символ после команды s
в качестве разделителя.
Когда мне нужно было работать между двумя каталогами быстро и более двух раз, следующий пример показывает, что работает для меня:
$ pwd
/home/chris/tmp
$ ln -s /home/mythtv/video/tv/tmp
$ cd tmp
$ ls
$ cd../
$ mv 852f.mkv tmp
$ ls tmp
852f.mkv
$ rm -i tmp
rm: remove symbolic link 'tmp'? y
$ ls /home/mythtv/video/tv/tmp
852f.mkv
Иногда проще использовать мышь , если вы используете хороший эмулятор терминала на графическом рабочем столе. Или в screen
или современном эквиваленте вы можете использовать элементы управления с клавиатуры для копирования/вставки текста.
$ pwd
/some/long/path
скопируйте/вставьте этот путь в команду cd
(, т. е. дважды -щелкните по нему, чтобы выбрать все, или трижды, чтобы получить всю строку, если есть пробелы. Если да, то введите одну кавычку -перед вставкой ).
Затем используйте клавиши редактирования строки -вашей оболочки, чтобы отредактировать ее ранний компонент, например. в режиме Bash emacs
,
Если вы что-то нащупываете, это всего лишь cd
команда, так что ничего деструктивного она не сделает.
В cli вы можете использовать модификатор, как в этом примере:
$ mkdir -p foobar/foo/data/images/2020/01/14/0001/
mkdir: created directory 'foobar'
mkdir: created directory 'foobar/foo'
mkdir: created directory 'foobar/foo/data'
mkdir: created directory 'foobar/foo/data/images'
mkdir: created directory 'foobar/foo/data/images/2020'
mkdir: created directory 'foobar/foo/data/images/2020/01'
mkdir: created directory 'foobar/foo/data/images/2020/01/14'
mkdir: created directory 'foobar/foo/data/images/2020/01/14/0001/'
$ ^bar/foo^bar/bar^
mkdir -p foobar/bar/data/images/2020/01/14/0001/
mkdir: created directory 'foobar/bar'
mkdir: created directory 'foobar/bar/data'
mkdir: created directory 'foobar/bar/data/images'
mkdir: created directory 'foobar/bar/data/images/2020'
mkdir: created directory 'foobar/bar/data/images/2020/01'
mkdir: created directory 'foobar/bar/data/images/2020/01/14'
mkdir: created directory 'foobar/bar/data/images/2020/01/14/0001/'
Пояснение:
Первая команда создает вложенные каталоги, начинающиеся с foobar. Вторая команда использует модификатор ^ для замены строки в предыдущей команде новой строкой. Легко сделать ошибку, набрав следующее:
^foo^bar^
Однако это изменит команду на
mkdir -p barbar/foo/data/images/2020/01/14/0001/
, потому что это также повлияет на ведущий foo. Чтобы избежать этого, вы можете использовать некоторые символы до или после предполагаемой строки.
В этом примере я использовал mkdir, но cd аналогичен. ХТН.