長い名前のLinux mvファイル


19

Linuxでは、時々次のようにファイル名を変更します。

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

別のディレクトリに移動するのではなく、ファイルの名前を変更するだけです。

そのコマンドの簡略版を実行できるコマンドはありますか?私は次のようなものを考えています:

mv dir1/dir2/dir3/file.txt  file.txt.old

または、次のようなもの(名前に追加するだけです):

mv dir1/dir2/dir3/file.txt  {}.old

私の目標は、完全なパスを再度指定する必要がないことです。

私が書いたそれらの「例」が機能しないことは知っていますが、それは私が何を達成したいのかという考えにすぎません。

ディレクトリにcdする必要はありません。


8
ディレクトリに移動してみませんか?高速で問題を解決します。
マイケルハンプトン

私はこの同じ場所から多くのサブディレクトリを扱っています。毎回この親ディレクトリに戻る必要がある場合は遅いです
サンティアゴarizti

3
他のディレクトリに変更する必要があるとは誰も言わず、必要なディレクトリだけに変更しました。
マイケルハンプトン

これ(cd dir1/dir2/dir3 && exec mv file.txt{,.old})は、外部コマンドの呼び出し中にing execを回避fork()するため、サブプロセスなしのコードと実質的に同じパフォーマンスを持っていることに注意してください。
チャールズダフィー

回答:


45

単一のファイルを試す

mv dir1/dir2/dir3/file.{txt,txt.old}

X{a,b}コンストラクトがに展開される場所ではXa Xb、次を使用してプレビューできます

echo dir1/dir2/dir3/file.{txt,txt.old}

ニーズに合っているかどうかを確認します。

注意:

  1. 複数のファイル用

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

あなたが望むものに拡張する可能性は低いです。(これはfile.txt file1.txt.old file2.txtの混合に展開されます...)

  1. {txt,txt.old}{,.old}コメントごとに短縮できます

  2. ディレクトリ名が明確な場合、ワイルドカードを使用できます。

    mv *1/*2/d*/*.{,old}
    

複数のファイルを使用する場合 rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

-n効果的な名前の変更をドロップします。


1
いいですね、私はこの拡張方法を知りませんでした!ありがとう
サンティアゴarizti

14
うまくmv dir1/dir2/dir3/file.txt{,.old}いかず、さらに短くなりますか?
ジョシュ

3
@Joshはい、完全に機能し、キーストロークが少なくて済みます。私はこのコンストラクトを非常に定期的に使用しています。
rlf

2
あなたは年間のLinuxのシェルを使用して、まだ新しいトリックのすべての時間を見つけることができますどのようにそれは面白いです
サンティアゴarizti

これらの「トリック」はすべて、bash言語で正式なトレーニングを受けていればもっと明白になると思いますが、うまくやっていくだけのことを学んでいます。
サンティアゴarizti

6

このコマンドrenameは、一致したすべてのファイルの名前を変更します。その主な目的は複数のファイルの名前を変更することですが、Perl式が1つのファイルのみに一致する場合、この単一のファイルのみの名前を変更します。詳細およびディストリビューション固有の構文については、マンページを参照してくださいman rename

使用例:「/path/file.txt」の名前を「/path/file.txt.old」に変更します。

rename 's/file.txt/file.txt.old/g' /path/file.txt

短い表記(シャロンブのおかげ):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

ドライランで使用しますrename -n

その他の例と詳細は、https://thepcspy.com/read/bulk-rename-files-in-ubuntu/で見つけることができます


かっこいい、名前変更コマンドについては知っていたが、それができることをまったく知らなかった、ありがとう!
サンティアゴarizti

6
残念ながら、Linuxディストリビューションごとにrenameコマンドが異なり、動作がまったく異なります。
カスペルド

1
.oldファイル名に追加することにより名前を変更するこの特定のタスクについては、おそらくrename 's/$/.old/' /path/to/file.txtrename '$_.=".old"' /path/to/file.txt
shalomb

@ファビアン-私は、ピッキングではなく、OPが探している頻繁に使用されるイディオムのように見える「最短手」を目指しているだけです:)
shalomb

4

1回限りの場合、現在のディレクトリを変更したくない場合は、サブシェルを使用するだけです。

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

サブシェルcd内にいるため、実際のシェルでディレクトリを変更していない


4
より高速で安全に使用&& exec mvできます。この方法では、cd失敗した場合に名前の変更を試行せずexec、サブシェルを消費するため、パフォーマンスの低下を回避できます。
チャールズダフィー

同意し&& 、私が言ったように、1つオフの場合については、私はサブシェルのコストを心配しないだろう(それをシンプルに保つ:簡単にそれを行う方法を覚えておくことが可能であることがIMOより重要である)
アダム・

私はあなたが効率的な方法は、あなたがそれを例に非効率的なルートを行っていないのに役立ちます覚えて、一方向にしか覚えておくつもりならと主張していると思いません問題。
チャールズダフィー

4

@archemarの{}展開を使用するソリューションが気に入っています。コマンドラインを既に起動しているときに使用できるためです。完全性のその他の可能性は次のとおりです。

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(引用符は、名前にスペースまたは他の単語区切り文字がある場合にのみ必要です)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

ノート:

  • これはbash構文です。別のシェルを使用している可能性があります
  • mymv 妥当な文字列であれば、「my move」にmymvを使用しました。
  • 関数定義は.bash_profileに入れることができます

別のもの:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

しかし

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(@Adamおよび@CharlesDuffyより)は、CDが失敗した場合に備えて間違いなく優れています。


1
使用しないでくださいmmv、すでにこの方法と名付けられたプログラムがあります。
glglgl

1
@glglgl完了:)
Law29

2

mvコマンドを短縮するためにサブディレクトリを入力したいが、その後現在のディレクトリに戻りたい場合は、2つの方法があります。1つは、サブシェルにcdand を配置することですmv(既に提案されているように)。

もう1つは、ディレクトリの使用pushdpopd変更です。

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

pushdコマンドは次のようであるcd、それは最初のスタックにカレントディレクトリの名前をプッシュ除き、。popdスタックからトップ名を削除し、そのディレクトリに変更します。


pushdまたpopd、インタラクティブな使用を目的とした拡張機能です。POSIXは明示的に「結果は指定されていません」としてリストします。
チャールズダフィー

2

ただやる

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

0

mv something{.txt,.txt.old}を含む解決策は「bashism」を使用しています。一般的な変数操作を使用して、より移植性の高い方法が必要な場合:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

2
適切なPOSIX仕様については、pubs.opengroup.org / onlinepubs / 009695399 / utilities /…を参照してください${var/text/replacement}。これはバシズムそのものです。
チャールズダフィー

@CharlesDuffyああ...あなたは私を悲しくさせます:(
オリビエデュラック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.