1つのコマンドで "rm -rf targetdir && mv sourcedir targetdir"と同じことを実行できますか?

1つのコマンドで

「あるファイルを別のファイルに置き換える」操作を説明する方法はいくつかありますが、ここで重点的に説明する方法はコマンドを使用して実行できる方法です。

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(または配列を持つ他のシェル)が必要です。私はそれが使用されたと思い、両方ともmvPOSIXに準拠しています。rmfind

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"
}

おすすめ記事