フォルダーパスを繰り返さずに、別のフォルダーでコマンドを実行するにはどうすればよいですか?


73

そこにある巧妙なコピーを行うと、やってなくても、ファイルを複製するための操作やコマンドを移動する方法cd、その後、mv同じフォルダで、後は?

たとえば、次を実行する必要があります。

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

ファイルを移動するディレクトリは同じであることに注意してください。ただし、パス全体をもう一度入力する必要があり、時には迷惑になります。操作が同じパスで行われるため、パス全体を再度入力することなく、別の方法でそれを行うことができるかどうか知りたいです。


9
これには多くの賛成票があるとは信じられません。それは重複だunix.stackexchange.com/questions/35782/...unix.stackexchange.com/questions/66889/...
user13107

13
@ user13107異なる言い回しなど、質問する方法はたくさんあります。そして、答えが「ブレース展開」と呼ばれることを知らない場合、すぐにそれを見つけることができないかもしれません。
-slhck

2
彼らは別のサイトで重複していない@ user13107
user151019

1
マーク、ありがとう、重複に関するそのルールを知りませんでした。@slhckはい。わかります。Unix.SEでの私の質問が重複して閉じられ、この質問がとても人気になったので、私はただイライラしました。
user13107

3
@ user13107、それはあなたが正しいサイトに投稿すると得られるものです
サミュエル・エドウィン・ウォード

回答:


125

ブレース拡張を使用するだけです:

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

これは次の記述と同等です。

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

もちろん、ブレース展開により、より多くの引数を指定できます。あなたも、あなたが実行することができ、テストフォルダーのカップルを作成するために、例えば、それに範囲を渡すことができmkdir test_{a..z}、そしてバッシュ4から始まる、あなたはのように、同様にゼロパディングシーケンスを作成することができtouch foo{0001..3}、作成したfoo0001foo0002foo0003バッシュハッカーウィキはあなたのための例のカップルとの記事があります。

2つの異なるコマンドを使用する必要がある場合は、@ Ignacioの回答のように、cd最初にサブシェルを使用し、そこから使用します


5
brace拡張について知りませんでした、ありがとう!
ヴァルターシルバ

私が試したが、うまくいかないようだ: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
のようにBashを使用/bin/bashしてい/bin/shて、ブレース展開をサポートしていないシバンまたは他のシェルにあるスクリプトを使用していないのですか?実行する場合setSHELLOPTS含まれていますbraceexpandか?
slhck

22
間にスペースがあってはならないことに注意してくださいfile.txt,file2.txt
slhck

9
あなたは変化しない部分でのタイプミスを防ぐために、それさえも短くすることができますmv /folder1/folder2/folder3/file{,-2013}.txt
月ファブリ

74

サブシェルで操作を実行します。

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

作業ディレクトリの変更は、親シェルに伝播されません。


11
+1:私はそれが好きです。ブレース展開のトリックよりもシェル全体でより移植性があります(きちんとしていますが、移植性は劣ります)
オリヴィエデュラック

@Olivier、ブレースの拡張が移植性がないと思う理由は何ですか?どのシェルをサポートしていないのですか?
アレクシス

5
@alexisブレースの展開はPOSIXでは指定されていないため、「設計上」移植性がありません。ashdashksh88古いBourneシェルがそれをサポートしていないシェルの例です言うまでもありません。
jlliagre

@jlliagreあなたが言及したシェルのうちどれが完全にPOSIXに準拠していますか?これは、たとえPOSIXであったとしてもブレースが展開されないことを意味します。ksh88はPOSIXが批准される前でした。少なくともksh93にアップグレードする必要があります。Linuxで気になるのは、小さな組み込みディストリビューション(busybox、iirc?)およびレスキューディスクで使用されるため、ashとdashだけです。
カズ

2
@Kaz私はシェルコマンドの移植性に関心があり、それらがインタラクティブであるかどうかは重要ではありません。もちろん、あなたはこれを気にしないことは確かに自由ですが、人々がそうでないと思うことを受け入れてください。常にbashまたはbarce-expansionをサポートするシェルを使用するという事実は、それが全員の場合であることを意味しません。
jlliagre


11

変数を設定できます。もちろん、これには変数を残しておくという副作用があります。

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

そして、もちろん、コマンドライン全体をサブシェルに入れる(D="/folder1/folder2/folder3"; mv "$D"/file.txt "$D"/file-2013.txt)か、単にunsetコマンドを最後に追加することで、変数を残す副作用を回避できます。(引用符を「ベストプラクティス」として追加しました。引用符を常に使用する習慣があれば、特殊文字を含むパス名が来たときに停止して頭を悩ませる必要はありません。)
Scott

@Scottは、サブシェルを使用して副作用を排除するcd場合、変数を設定するよりも簡単です。ない多くのより簡単に、私は認めます。
アイザックラビノビッチ

2

私は他のソリューションが好きですが、bash配列、pushd、popdを備えたスクリプトとして実装された別のソリューションがあります。

#!/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は可能な限り簡単な方法で質問に直接回答しますが、Valterはautopopの回答も気に入っています。

pushd /folder1/folder2/folder3/; mv file.txt file-2013.txt; popd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.