ディレクトリを作成して同時に移動できるワンライナーはありますか?


150

私は多くのことを繰り返しています:

mkdir longtitleproject
cd longtitleproject

ディレクトリ名を繰り返さずに1行でそれを行う方法はありますか?私はここでバッシュしています。




1
mkdir longtitleprojectその後cd !^
user262826

回答:


160

組み込みコマンドはありませんがmkdir、then を呼び出す関数を簡単に作成できますcd

mkcd () {
  mkdir "$1"
  cd "$1"
}

このコードを~/.bashrcファイルに(または~/.kshrckshユーザー、または~/.zshrczshユーザー用に)配置します。という関数を定義しますmkcd"$1"関数を実行すると、関数の引数に置き換えられます。

この単純なバージョンにはいくつかの欠陥があります。

  • サブディレクトリのチェーンを一度に作成することはできません。修正:-pオプションをに渡しますmkdir。(これは、タイプミスが検出されないリスクを高めるため、望ましい場合と望ましくない場合があります。たとえば、mkcd mydierctory/newsub喜んで作成する場合mydierctoryや、既存のmydierctory/newsubを作成する場合です。)newsubmydirectory
  • 引数が始まる場合-、ただではありません-し、mkdirそしてcdオプションとしてそれを解釈します。それがちょうどなら-cdそれを意味するように解釈します$OLDPWD+0桁以上の数字が続く場合cd、zshはそれをディレクトリスタック内のインデックスとして解釈します。--引数の前に渡すことで、最初の問題を修正できますが、他の2つの問題は修正できません。./引数が相対パスの場合、引数の前に追加することにより、これらの問題をすべて修正できます。
  • mkdir従わないがCDPATH、従わないcdので、もしあなたが(CDPATH明らかに.やや珍しい構成)で始まらない値に設定したなら、cd作成されたディレクトリとは異なるディレクトリにあなたを連れて来るかもしれない。./相対パスの前に付けると、これが修正されます(CDPATH無視されます)。
  • 場合はmkdir失敗し、それが実行しようとしますcd。修正:&&2つのコマンドを分離するために使用します。

まだかなり簡単です:

mkcd () {
  case "$1" in /*) :;; *) set -- "./$1";; esac
  mkdir -p "$1" && cd "$1"
}

このバージョンには、1つのエッジケースで作成されたcdディレクトリとは異なるディレクトリに移動する可能性があります。シンボリックリンクmkdirmkcd含む引数が含まれている場合..。たとえば、現在のディレクトリが/tmp/heremylinkあり、へのシンボリックリンクである/somewhere/else場合、mkdir mylink/../foo作成しますが/somewhere/else/foo、にcd mylink/../foo変更しfooます。引数でシンボリックリンクを探すだけでは十分ではありません。シェルは独自の現在のディレクトリのシンボリックリンクも追跡するためcd /tmp/mylink; mkdir ../foo; cd ../foo、新しいディレクトリ(/somewhere/else/foo)ではなくに変更するため/tmp/fooです。これに対する修正は、最初にcdすべての..パスコンポーネントをビルトインで解決できるようにすることfoo/..です(以下の場合は使用する意味がありません)。foo存在しないため、mkdir表示する必要はありません..)。

私たちは、この頑強なバージョンをわずかに使い古したものにします:

mkcd () {
  case "$1" in
    */..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
    /*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
    /*) mkdir -p "$1" && cd "$1";;
    */../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
    ../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
    *) mkdir -p "./$1" && cd "./$1";;
  esac
}

(練習:なぜ最初のcd呼び出しにサブシェルを使用するのですか?)

mkdirが失敗した場合、現在のディレクトリを変更しないようにします。シェルで現在のディレクトリに変更する権限がない場合、cd-または$ OLDPWDで元に戻すことは十分ではありません。また、cdを呼び出すとOLDPWDが更新されるため、一度だけ実行する(またはOLDPWDを復元する)だけです。


また、前の行の単語を再入力する必要がない、それほど専門化されていない方法もあります。

  • を入力してcd からEsc .(またはAlt+ .)、前のコマンドの最後の引数を挿入します。
  • cd !$cd前のコマンドの最後の引数で実行されます。
  • を押しUpて前のコマンドラインを呼び出し、編集してに変更mkdircdます。

ありがとう!Esc 私にとって最も便利なようですが、キーシーケンスには特別な意味がありますか?
methodofaction

「前のコマンドの最後の単語を繰り返す」ための単なるBash(およびから継承されksh、で動作するzsh)シーケンスです。頻繁に使用します。
ギーコサウルス

31
@Gilles「Gilles」アカウントは実際には専門家のパネルによって共有されていると思い始めています。;-)
キース

@StephaneChazelas /a/b/..//は実際には動作しますが、動作しません/a/b/../c。一定。私は、より多くの聴衆に質問をしました。
ジル

1
mkcd() { mkdir -p "$1" && cd "$1"; }zsh(の私のインスタンス)で問題ではないようです。 mkdir -p /var/tmp/somewhere/else /tmp/here; cd /tmp/here; ln -s /var/tmp/somewhere/else mylink; mkdir -p mylink/../foo && cd mylink/../foo; pwd(セットアップを含み、/tmp/here/foo作成されたもの(および私が期待したもの)を表示します。 bashを誤って作成して変更し/var/tmp/somewhere/fooます。
アダム・カッツ

134

これが必要なワンライナーです。他の設定は必要ありません:

mkdir longtitleproject && cd $_

$_bash の変数は、前のコマンドに与えられた最後の引数です。この場合、作成したディレクトリの名前。で説明されているようにman bash

_         At  shell  startup,  set to the absolute pathname used to invoke
          the shell or shell script being executed as passed in the  envi
          ronment  or  argument  list.   Subsequently, expands to the last
          argument to the previous command, after expansion.  Also set  to
          the  full  pathname  used  to  invoke  each command executed and
          placed in the environment exported to that command.  When check
          ing  mail,  this  parameter holds the name of the mail file cur
          rently being checked."$_" is the last argument of the previous command.

シェル履歴で前のコマンドの最後の引数を与えるためではcd $_なく、前のコマンドの最後の引数を取得するために使用します。cd !$cd !$

cd ~/
mkdir folder && cd !$

あなたは家に帰る(または〜/)

cd ~/
mkdir newfolder && cd $_

あなたは家の下の新しいフォルダになります!! (または〜/ newfolder)


23
なぜ地球上で、この1は受け入れ答えではありません
JSmyth

1
私は同意@JSmyth、これはネイティブのシェル機能使用していますワンライナーである
sming

OPは2つのコマンドの使用を避けようとしていると思います。この答えは(ほとんど)実行するのと同じくらい有効ですmkdir foo && cd fooが、便利ではありません。
-josemigallas

7
OPは、ディレクトリ名を繰り返す必要はありませんワンライナーを求めているが、これはそれである
ヘスス・カレラ

これはあなたが参照している、または他の人がドキュメント/チュートリアルで使用しているのを見た伝統的なワンライナーです。実際には、3つの完璧な答えがあります。これは、@ jordan-harrisによるものと、選択された答えです。セットアップと設定によって異なります。
ウェイド

30

次のように1時間ごとに入力するため、この動作をスクリプト化することは私には決してありませんでした...

$ mkdir someDirectory<ENTER>
$ cd !$

bash !$は最後の行の最後の単語で親切に置き換えます。つまり、入力した長いディレクトリ名。

また、このような状況では、ファイル名の補完があなたの友達です。新しいディレクトリがフォルダ内の唯一のファイルである場合、クイックダブルTABは、再入力せずに新しいディレクトリを提供します。

bashを使用すると、他の回答が示唆するような一般的なタスクをスクリプト化できるので便利ですが、bashが提供するコマンドライン編集機能を学習して、別のマシンで作業しているときに構文が失われないようにすることをお勧めしますカスタムスクリプトが提供する砂糖。


1
このような最も重要なbashの癖について調べる良い場所はありますか?
dominicbri7

@ dominicbri7は、一般的に同じグーグルで「bashのコマンドライン編集」の下に来ることは、トップの結果として、以下の与えweb.mit.edu/gnu/doc/html/features_7.html具体的には、!$は、Word指定子の例を参照され GNUを。 org / software / bash / manual / bashref.html#Word-Designators
ロブ

17

あたりとしてどのようにカスタマイズあなたは、生産性を向上させるためにあなたのシェルプロファイルに行っていますか?、これは私がそれを行う方法です:

# make a directory and cd to it
mcd()
{
    test -d "$1" || mkdir "$1" && cd "$1"
}

ディレクトリが既に存在する場合にも機能することを意味します。


4
-pmkdir のオプションはエラーを抑制します。
グレンジャックマン

1
mcdは既存のコマンドです。例を挙げたばかりですが、mkcdより短い文字なので、自分で使用しました。
-Dharmit

@Dharmit Shah:既存のmcdコマンドは何ですか?このコマンドを提供するパッケージまたはプロジェクトはどれですか?
ミケル

2
mtoolsはmcdコマンドを提供します。そのマニュアルページには、「MS-DOSディスク上のmtools作業ディレクトリを変更するためにmcdコマンドが使用されています。」
Dharmit

13

Oh My Zshを使用している場合、まさにこれを行うtakeというコマンドがあります。これは次のようになります。

take myfolder

私は実際にこれを偶然見つけました。私が見たところ、それはOh My Zsh GitHub wikiのこのチート攻略にリストされています。これは非常に便利なコマンドであり、明らかに自分で作成するのは非常に簡単です。


1
私は知らなかったtake:)完璧!btw-Oh My Zshを使用したiTerm2。実際には、3つの完璧な答えがあります。これは@jesús-carreraによるもので、選択された答えです。セットアップと設定によって異なります。
ウェイド

3

または、オンザフライで短い変数を作成して2回使用することもできますx = longproject ; mkdir $x ; cd $x-私はそれがシェルスクリプト関数を使用するよりもまだ長いことを認めています:)


0

言及に値するわずかなバリアントを次に示します。

function mkdir() {
    local dir=$1
    command mkdir "$dir"  &&  cd "$dir"
}

これをに追加する~/.bash_profileと、標準のコマンドではなく上記の関数を実行するようになることを除いて、mkdir通常どおり(一度使用すると)使用できます。sourcemkdir

これは、Gillesが受け入れた回答に従って入力を検証するものではありませんが、組み込みを(効果的に)オーバーライドする方法を示しています。

ドキュメントから(わずかに言い換え):

command mkdir [args]という名前のシェル関数mkdirargs無視して実行されmkdirます。シェルの組み込みコマンドまたはPATHの検索で見つかったコマンドのみが実行されます。名前のシェル関数が存在する場合ls、実行されているcommand ls機能の中には、外部コマンドを実行しますls代わりに再帰関数を呼び出すと

builtin同様の結果が得られると思いますcommand


間違いなく引用する必要があります$dir
ジェフシャラー

@Jeffは同意しましたが、受け入れられた答えには必要な検証がすべて含まれています。のcommand代替としての使用を提示しています。
ARJ

0

BASH、ZSH、またはKSHにヘルパー関数を追加する

mkcd環境へのコマンドを1行で作成します

echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc


-1

上記の回答を自動化し、1回限りの実行可能スクリプトを作成しました。

fun='
mkcd ()
{
    mkdir -p -- "$1" && cd -P -- "$1"
}'

echo "$fun" >> ~/.bashrc

これを新しいファイルにコピーして、ターミナルmkcd.sh一度だけ実行しますbash mkcd.sh。次にsource ~/.bashrc、現在のセッションで動作するように実行します。

この後mkcd some_dir、そのディレクトリに直接作成して入力するために使用できます。


ファイルに追加することを唯一の目的とするスクリプトを(ファイルに)書くことをお勧めし~/.bashrcます(既に回答済み)。そして、このmkcd.shスクリプトの作成をどのように提案しますか?エディタを使用して、おそらく?これは単なる編集よりも多くの作業のように見えます~/.bashrc。これは、受け入れられた答えに対してどのような利点がありますか?…………………………………………………………PSこれは引用の問題があるため失敗します。
スコット

申し訳ありませんが、答えに書いたとおり、上記の答えを使用しました。動作します。あなたが私を信じないなら、それを試してください。そして、試さないことについては、今日、bashとpythonでそのようなスクリプトを書くのに丸1日を使いました。
subtleseeker

あなたが書いたものを試しました。機能しませ
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.