Klasör yolunu tekrarlamadan başka bir klasörde komutları nasıl uygularım?


73

Bir var mı zeki kopyasını yapmak ve bir yapmak zorunda kalmadan, işlemleri veya dosya çoğaltmak için bir komut taşımak için bir yol cddaha sonra, mvaynı klasör de, sonra?

Örneğin, aşağıdakileri çalıştırmam gerekiyor:

mv /folder1/folder2/folder3/file.txt /folder1/folder2/folder3/file-2013.txt

Dosyayı taşıdığım dizinin aynı olduğunu unutmayın, ancak tüm yolu tekrar koymak zorunda kalıyorum ve bazen sinir bozuyor. Tüm yolu tekrar koymak zorunda kalmadan bunu yapmanın başka bir yolu olup olmadığını bilmek merak ediyorum , çünkü işlem aynı yolda yapılacaktı.


9
Bunun bir sürü olumlu olduğuna inanamıyorum. Bu, yinelenen bir unix.stackexchange.com/questions/35782/… ve unix.stackexchange.com/questions/66889/…
kullanıcı13107

13
@ user13107 Farklı ifadeler dahil bir soru sormanın birçok yolu vardır. Ve cevabın "ayraç genişletme" olarak adlandırıldığını bilmiyorsanız, onu hemen bulamayabilirsiniz.
slhck

2
@ user13107 onlar farklı bir sitede yani yinelenen değil
user151019

1
Mark, Teşekkürler, kopyalarla ilgili bu kuralı bilmiyordum. @slhck Evet. Anlıyorum. Sadece hayal kırıklığına uğradım, çünkü Unix.SE hakkındaki sorumu çoğaldıkça kapattım ve bu çok popüler oldu.
user13107

3
@ user13107, doğru sitede yayınlamak için aldığınız şey
Samuel Edwin Ward

Yanıtlar:


125

Basitçe ayraç genişletme kullanın :

mv /folder1/folder2/folder3/{file.txt,file-2013.txt}

Bu yazmaya eşdeğerdir:

mv /folder1/folder2/folder3/file.txt /folder1/folder2/folder3/file-2013.txt

Parantez genişletme elbette daha fazla argüman sağlar. Hatta Test klasörlerin bir çift oluşturmak için, kendisine örn aralıkları geçebilir, Çalıştırabileceğiniz mkdir test_{a..z}ve Bash 4 ile başlayarak, olduğu gibi, hem de sıfır yastıklı dizileri oluşturabilir touch foo{0001..3}yaratan, foo0001, foo0002ve foo0003. Bash Hackerlar Wiki sizin için örnekler bir çift bir makale vardır.

İki farklı komut kullanmak zorundaysanız , @ Ignacio'nin cevabında olduğu gibi bir alt kabuk ve cdorada kullanın .


5
braceGenişleme hakkında hiçbir şey bilmiyordum , teşekkür ederim!
Valter Silva

Denedim ve işe yaramadı gibi görünüyor:meniac ~: mv /tmp/f1/f2/f3/f4/f5/f6/{file.txt, file2.txt} mv: cannot stat ``/tmp/f1/f2/f3/f4/f5/f6/{file.txt,': No such file or directory
Valter Silva

5
Eğer olduğu gibi, Bash kullandığınızdan emin misiniz /bin/bashve sahip bir komut değiliz /bin/shshebang veya bağ genişlemesini desteklemediği diğer bazı kabukta? Eğer koşarsan set, SHELLOPTSiçeriyor braceexpandmusun?
slhck

22
file.txt,Ve arasında boşluk olmaması gerektiğini unutmayın file2.txt.
slhck

9
Değişmeyen kısımdaki yazım hatalarını önlemek için daha da mv /folder1/folder2/folder3/file{,-2013}.txt
kısaltabilirsiniz

74

İşlemi bir alt kabukta çalıştırın.

( cd /folder1/folder2/folder3 && mv file.txt file-2013.txt )

Çalışma dizini değişikliği ana kabuğa yayılmayacak.


11
+1: Kabuklar arasında küme genişleme numarasından daha temiz (taşınabilir, ancak daha az taşınabilir olan) hoşuma gidiyor
Olivier Dulac 17:13

@ Olivier, ayraç genişlemesinin taşınabilir olmadığını düşündüren nedir? Bunu desteklemeyen hangi aklınız var?
alexis,

5
@alexis Brace genişletme POSIX tarafından belirtilmez, bu nedenle "tasarım" tarafından taşınabilir değildir. ash, dash, ksh88Eski Bourne kabuk desteklememesi kabukların örneğin söz değil.
jlliagre

@jlliagre Bahsettiğiniz mermilerden hangisi tamamen POSIX uyumlu? Bu, POSIX olsa bile ayraç genişlemelerine sahip olmayacakları anlamına geliyor. ksh88, POSIX onaylanmadan önceydi; en azından ksh93'e yükseltmelisin. Linux'ta umursayan sadece iki kişi kül ve çizgidir çünkü bazı küçük gömülü dağıtımlarda (meşgul kutusu, iirc?) Ve kurtarma disklerinde kullanılırlar.
Kaz,

2
@Kaz Shell komutlarının taşınabilirliğini ve etkileşimli olup olmadıklarını önemsiyorum. Tabii ki, bu konuyu umursamama konusunda kesinlikle özgürsünüz ama lütfen insanların başka türlü düşündüğünü kabul edin. Her zaman bash veya barikat genişlemesini destekleyen bir kabuk kullanmanız herkesin durumu anlamına gelmez.
jlliagre


11

Bir değişken ayarlayabilirsiniz. Elbette bu değişkenleri etrafta bırakmanın yan etkisine sahiptir.

D=/folder1/folder2/folder3; mv $D/file.txt $D/file-2013.txt

Ve elbette, tüm komut satırını bir alt kabuğa koyarak değişkenleri etrafında bırakmanın yan etkisinden kaçınabilirsiniz: (D="/folder1/folder2/folder3"; mv "$D"/file.txt "$D"/file-2013.txt)ya da sadece unsetsonuna bir komut ekleyerek . (“En iyi uygulama” olarak alıntılar ekledim; her zaman alıntı kullanma alışkanlığı yaşarsanız, özel karakterler içeren bir yol adı geldiğinde başınızı durduracak ve çizmeyeceksiniz.)
Scott

@Scott yan etkileri ortadan kaldırmak için bir alt kabuk kullanacaksanız, cdbir değişken ayarlamaktan daha kolaydır . Çok kolay değil , itiraf ediyorum.
Isaac Rabinovitch

2

Diğer çözümleri de severim, ancak bash dizileri, pushd, popd içeren bir komut dosyası olarak uygulanan başka bir şey daha var:

#!/bin/bash
set -e
# from http://stackoverflow.com/a/246128/178651
script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# paths relative to the script
relative_paths=( \
path1 \
path2 \
path3 \
path4
)

for relative_path in "${relative_paths[@]}"
do
  pushd "$script_path/$relative_path" > /dev/null 2>&1
  pwd
  mv filename1 filename2
  # could do other stuff in this directory...
  popd > /dev/null 2>&1
done

pushd "$script_path" > /dev/null 2>&1
# could do other stuff in same directory as script...
popd > /dev/null 2>&1

1

Slhck, soruyu doğrudan en basit şekilde yanıtlar, ancak Valter aynı zamanda otomatik yanıtı da sever, işte aynı satırda olanlardan biri;

pushd /folder1/folder2/folder3/; mv file.txt file-2013.txt; popd
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.