「あるファイルを別のファイルに置き換える」操作を説明する方法はいくつかありますが、ここで重点的に説明する方法はコマンドを使用して実行できる方法です。
mv /that/there/someotherfile /this/here/somefile
この例では、/that/there/someotherfile
およびは/this/here/somefile
現在のファイルシステムに存在する通常のファイルでなければなりません。
すべてが順調に進むと、上記のコマンドを実行した後、「以前に知られている」ファイルは消えますが、/that/there/someotherfile
その内容はファイルの新しい内容になります/this/here/somefile
。後者の前のコンテンツは「上書き」されます。
ここで、「あるディレクトリを別のディレクトリに置き換える」同様の操作を考えてみましょう。たとえば、/path/to/targetdir
一部のディレクトリをディレクトリで上書きします/some/other/path/to/sourcedir
。私はこれを行うことができます
rm -rf /path/to/targetdir && mv /some/other/path/to/sourcedir /path/to/targetdir
有効な「やや標準」1コマンドを使用してこれを実行できますか?関連する2つのディレクトリの内容に関係なく?
空/path/to/targetdir
のディレクトリなら、
mv -T /some/other/path/to/sourcedir /path/to/targetdir
...仕事をします。
/path/to/targetdir
また、両方のディレクトリの下に存在しない相対パスを含まず、両方のディレクトリの下に存在するすべての相対パスが同じタイプのファイルシステムエントリを指すことを知っています(/some/other/path/to/sourcedir
つまり、すべてディレクトリまたは一般ファイルなど)。は以下を得ることができます閉鎖上記の作業に
rsync -a --remove-source-files /some/other/path/to/sourcedir/ /path/to/targetdir
もちろん、rm -rf
上記の+シーケンスをカプセル化するために2つのスクリプトや関数を実装することは難しくありませんが、ある程度mv
標準のUnixコマンドですでに使用できるものを実装することを避けたいと思いました。
1私はこの質問に対する答えが許可された一連の命令に対する個人の見解に決定的に依存していることを知っていますが、残念ながらここでは手を振るよりも優れたものを提供することはできません...たとえば、cp
と思います。mv
それほど標準的ではありませんが、この場合でもこれらのコマンドが使用するオプションの一部はそうでない可能性があります。「次までPOSIXを強制」)、上記の意味では、単一のコマンドを使用して「あるディレクトリを別のディレクトリに置き換える」という普遍的な方法はありません。その場合は、許可された一連のコマンドを自由に定義して、コマンドを便利で面白いものにします。つまり、許可された一連のコマンドを選択するときは、あなたの好みに従う準備ができています。
2有名な最後の言葉。
ベストアンサー1
rsync
一般的な再起動の可能性を忘れた場合、この非常に危険なコマンドが機能する可能性があります。
rsync -av --remove-source-files --delete-before /path/to/source/ /path/to/target
しかし、いくつかの注意事項があります。
- ファイルを移動するのではなく、ファイルをコピーして元のファイルを削除します。これは、同じファイルシステムにある大容量ファイルの場合に問題になる可能性があります。
- ソースディレクトリは削除されません。これが問題の場合は、2つのコマンドに戻って元の
rm && mv
設定に戻すこともできます。 - これはPOSIXではありません
全体的に私はこのrm && mv
アプローチを好むと思います。このバージョンにはbash
(または配列を持つ他のシェル)が必要です。私はそれが使用されたと思い、両方ともmv
POSIXに準拠しています。rm
find
rmmv() {
local args=("$@") target
if [ $# -eq 0 ]
then
echo "${0##*/}: missing file operand" >&2
exit 1
elif [ $# -eq 1 ]
then
echo "${0##*/}: missing file operand after '${args[0]}'" >&2
exit 1
fi
target="${args[@]: -1}"
unset "args[${#args[@]}-1]"
if [ -d "$target" ]
then
# Directory target; remove its contents
( cd -P -- "$target" && find . -depth -path './*' -exec rm -rf {} + )
elif [ "${#args[@]}" -gt 1 ]
then
# Multiple sources but not a directory
echo "${0##*/}: target '$target' is not a directory" >&2
exit 2
fi
# Do it
mv -- "${args[@]}" "$target"
}