Bir komutu argüman olarak bir dizinle, sonra cd'yi aynı şekilde çalıştırmak nasıl? “Böyle bir dosya veya dizin yok”


15

Aşağıdakileri yapmak için kısa bir işlev kurmak istiyorum. Diyelim ki 'file.tex' dosyasını belgeler dizinime taşıyorum:

mv file.tex ~/Documents

Sonra, cdbu dizine istiyorum :

cd ~/Documents

Bunu yapabilmek için bunu herhangi bir dizine genelleştirmek istiyorum:

mv file.tex ~/Documents
follow

ve followkomutun hedefi önceki komuttan okumasını sağlayın, ardından buna göre çalıştırın. Basit bir dizin için bu çok zaman kazandırmaz, ancak iç içe geçmiş dizinlerle çalışırken, yalnızca

mv file.tex ~/Documents/folder1/subfolder1
follow

Ben nispeten basit olacağını düşündüm ve böyle bir şey yapabileceğini:

follow()
{
    place=`history 2 | sed -n '1p;1q' | rev | cut -d ' ' -f1 | rev`
    cd $place
}

ama bu işe yaramıyor gibi görünüyor. Eğer yankı $placeyaparsam, istenen dizeyi alırım (ile test ediyorum ~/Documents), ancak son komut geri döner

No such file or directory

Dizin kesinlikle var. Kayboldum. Bana yardımcı olabilir misin?


file.texOrijinal konumda sakıncası yoksa , sembollerin çok iyi bir alternatif olduğunu belirtmek isterim, çünkü sadece bir kez bağlantı kurmanız gerekir ve daha sonra her zaman en son sürüme işaret eder.
Kroltan

5
Daha kolay yol: önceki komutun son jetonunu değiştirmek için cd alt + .yazın. Son jetonların tarihinde daha ileri gitmek için tekrarlayın. (Çünkü değil arg belirteci demek foo &kıskaçlar &Bir sayısal argüman kullanabilirsiniz nihai ifadesi olarak.) (Kaçış-3 alt + ile. Örneğin).
Peter Cordes


Yanıtlar:


18

Bir işlevi tanımlamak yerine, $_tarafından önceki komutun son bağımsız değişkenine genişletilen değişkeni kullanabilirsiniz bash. Yani kullanın:

cd "$_"

mvkomuttan sonra .

Geçmiş genişletmeyi de kullanabilirsiniz:

cd !:$

Bir işlev kullanmanız gerekiyorsa:

follow () { cd "$_" ;}

$ follow () { cd "$_" ;}
$ mv foo.sh 'foo bar'
$ follow 
foo bar$ 

Not: Bu yanıt, konum parametreleriyle uğraşırken kullandığınız komut satırı bağımsız değişkenleri biçimini hedefler. Örneğin, diğer formatlar mv -t foo bar.txtiçin önceden belirli kontroller eklemeniz gerekir, o zaman bir sarıcı uygun olacaktır.


Geçmiş genişlemeniz (cd!: $) Mükemmel çalışıyor. Teşekkür ederim. Ancak, diğer (cd "$ _") yapmaz: mv file.tex ~ / Downloads / cd "$ _" bash: cd: __bp_preexec_invoke_exec: Böyle bir dosya veya dizin yok Cevabınızı tamamen doğru olarak memnuniyetle kabul edeceğim ve teşekkür ederim.
Ateş

Ben her zaman (biraz atık) ya cd !$da yazdım cd $(dirname !$). $_Değişken hakkında bilmiyordum !
Kalvin Lee

Şimdi mv -t ~/Documents file.texbunun yerine ne yaparsam mv file.tex ~/Documents? Alt satırda, bunun genel durumda çözülebileceğinden emin değilim ... etraftaki bir sarmalayıcı işlevi veya yeniden yapılanmaların mvdaha iyi olabileceği ...
CVn

@ MichaelKjörling Basit bir şekilde çalışmaz ... Bu örnek OP'nin kenar (veya tümü) vakalarını değil, sadece davayı kapsamasıdır.
heemayl

Kolona ihtiyacınız yoktur; !$eşittir !:$ve daha hızlı yazılır.
Wildcard,

14

Standart bash tuş bağlamalarında, kombinasyon Alt.önceki komut satırının son argümanını geçerli olana kopyalar. Yani, yazmak

$ mv foo ~/some/long/path/
$ cd <Alt><.>

verim verecek

$ mv foo ~/some/long/path/
$ cd ~/some/long/path/

ve kelimeden bile daha az yazım olurdu follow.

Daha fazla kolaylık için, Alt.kombinasyonu tekrarlamak önceki tüm komut satırlarının son argümanlarına göz atar.

Ek: Bu tuş bileşimine karşılık gelen bash komut adı yank-last-argveya insert-last-argument. Bu, bash kılavuzunda "Geçmişi Yönetme Komutları" altında veya daha ayrıntılı Bash Referans Kılavuzu'nda bulunabilir .)


1
Zekice. Teşekkürler! Bunun var olduğu hakkında hiçbir fikrim yoktu.
Ateş

@ Ateş Bu komutlar için referanslar ekledim, böylece çok daha ilginç tuş bağlamaları bulabilirsiniz (ve her zaman yaptığım gibi hemen tekrar unutun).
Dubu

1
<esc>O zaman .aynı sonucu almak için de kullanabilirsiniz <alt>+., kaçış için
kapak kilidini

1
@gnur vi (m) kullanıcı, sanırım. ;-)
Dubu

6

Kesinlikle tilde genişlemesinin parametre genişlemesinden önce gerçekleştiği ve kısa bir örnekle açıklanabilecek bir sorunla karşılaşıyorsunuz:

$ cd ~kaz
kaz $ var='~kaz'
kaz $ echo $var
~kaz
kaz $ cd $kaz
bash: cd: ~kaz: No such file or directory

Bu ile ele alınabilir eval. Her neyse, ihtiyacınız olacak eval, çünkü geçmişten komutlar alıyorsunuz ve bunlar gibi keyfi genişletmeler içerebilir:

$ mv file.tex ~/Documents/$(compute_folder_name foo-param)/subfolder1
$ follow

(Bu değerlerin yeniden genişletilmesinin artık gerçekleşen orijinal genişletmeyle eşleşmemesi gibi sorunlar vardır. Varsayalım compute_folder_name, bazı global değişkenleri artıran bir işlevdir.)


4
İhtiyacınız yok eval. (Şimdiye kadar) Ancak, genişleme dizisi problemlerini iyi tespit etmek. Tarihin evalburada genişlemesine dair daha fazla tavsiye edilebilirlikten bahsederseniz , bu benim görüşüme göre en iyi cevap olacaktır; hiçbiri Orijinal Poster'in çözümünün neden işe yaramadığını açıklamıyor .
Wildcard,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.