在bash中交换两个文件的最短途径

可以在bash中交换两个文件吗?

或者,他们可以换成比这更短的方式:

cp old tmp cp curr old cp tmp curr rm tmp 

将此添加到您的.bashrc中:

 function swap() { local TMPFILE=tmp.$$ mv "$1" $TMPFILE mv "$2" "$1" mv $TMPFILE "$2" } 

如果你想处理潜在的中间mv操作失败,请检查Can Bal的答案 。

请注意,这个和其他答案都不能提供primefaces性解决scheme,因为使用Linux系统调用和/或stream行的Linux文件系统是不可能的。 对于Darwin内核,请selectinterchangeata系统调用。

 $ mv old tmp && mv curr old && mv tmp curr 

效率稍高一点!

包裹成可重复使用的shell函数:

 function swap() { local TMPFILE=tmp.$$ mv "$1" $TMPFILE && mv "$2" "$1" && mv $TMPFILE $2 } 
 tmpfile=$(mktemp $(dirname "$file1")/XXXXXX) mv "$file1" "$tmpfile" mv "$file2" "$file1" mv "$tmpfile" "$file2" 

你真的想交换吗? 我认为值得一提的是,你可以自动备份覆盖文件与MV:

 mv new old -b 

你会得到:

 old and old~ 

如果你想要的话

 old and old.old 

您可以使用-S将〜改为您的自定义后缀

 mv new old -b -S .old ls old old.old 

使用这种方法,你可以更快地交换它们,只用2 mv:

 mv new old -b && mv old~ new 

结合最好的答案,我把它放在我的〜/ .bashrc中:

 function swap() { tmpfile=$(mktemp $(dirname "$1")/XXXXXX) mv "$1" "$tmpfile" && mv "$2" "$1" && mv "$tmpfile" "$2" } 

你可以简单地移动它们,而不是复制。

 #!/bin/sh # Created by Wojtek Jamrozy (www.wojtekrj.net) mv $1 cop_$1 mv $2 $1 mv cop_$1 $2 

http://www.wojtekrj.net/2008/08/bash-script-to-swap-contents-of-files/

适用于文件和目录的稍微有点硬化的版本:

 function swap() { if [ ! -z "$2" ] && [ -e "$1" ] && [ -e "$2" ] && ! [ "$1" -ef "$2" ] && (([ -f "$1" ] && [ -f "$2" ]) || ([ -d "$1" ] && [ -d "$2" ])) ; then tmp=$(mktemp -d $(dirname "$1")/XXXXXX) mv "$1" "$tmp" && mv "$2" "$1" && mv "$tmp"/"$1" "$2" rmdir "$tmp" else echo "Usage: swap file1 file2 or swap dir1 dir2" fi } 

这适用于Linux。 不知道有关OS X.

这是我在我的系统上使用的命令( $HOME/bin/swapfiles )。 我认为这是不好的。

 #!/bin/bash if [ "$#" -ne 2 ]; then me=`basename $0` echo "Syntax: $me <FILE 1> <FILE 2>" exit -1 fi if [ ! -f $1 ]; then echo "File '$1' does not exist!" fi if [ ! -f $2 ]; then echo "File '$2' does not exist!" fi if [[ ! -f $1 || ! -f $2 ]]; then exit -1 fi tmpfile=$(mktemp $(dirname "$1")/XXXXXX) if [ ! -f $tmpfile ]; then echo "Could not create temporary intermediate file!" exit -1 fi # move files taking into account if mv fails mv "$1" "$tmpfile" && mv "$2" "$1" && mv "$tmpfile" "$2" 

使用mv意味着你有一个更less的操作,不需要最终的rm,而mv只是改变目录条目,所以你没有使用额外的磁盘空间的副本。

诱惑然后是实现一个shell函数swap()或者其他的。 如果你非常小心地检查错误代码。 可能是可怕的破坏性。 还需要检查预先存在的tmp文件。

哈代的想法对我来说已经够好了。 所以我已经试过我的以下两个文件交换“sendingms.properties”,“sendsms.properties.swap”。 但是一旦我把这个函数作为相同的参数“sendingms.properties”调用,那么这个文件就被删除了。 避免这种失败,我为我加了一些线:-)

 function swp2file() { if [ $1 != $2 ] ; then local TMPFILE=tmp.$$ mv "$1" $TMPFILE mv "$2" "$1" mv $TMPFILE "$2" else echo "swap requires 2 different filename" fi } 

再次感谢哈代;-)

我在使用这里提供的任何解决scheme时遇到了一个问题:您的文件名将被切换。

我使用了basenamedirname来保持文件名不变*。

 swap() { if (( $# == 2 )); then mv "$1" /tmp/ mv "$2" "`dirname $1`" mv "/tmp/`basename $1`" "`dirname $2`" else echo "Usage: swap <file1> <file2>" return 1 fi } 

我已经在bash和zsh中testing过了。


*所以澄清这是如何更好:

如果你从以下开始:

 dir1/file2: this is file2 dir2/file1: this is file1 

其他解决scheme将最终:

 dir1/file2: this is file1 dir2/file1: this is file2 

内容被交换,但文件名保持不变 。 我的解决scheme使它:

 dir1/file1: this is file1 dir2/file2: this is file2 

内容名称被交换。

当然是mv而不是cp

 mv old tmp mv curr old mv tmp curr 

我在交付的一个工作脚本中有这个。 它被写成一个函数,但是你会调用它

 d_swap lfile rfile 

GNU mv有-b和-T开关。 您可以使用-T开关处理目录。

引号是用空格的文件名。

这有点冗长,但是我已经在文件和目录中多次使用了它。 可能会出现这样的情况,您想要使用目录的名称来重命名文件,但这不是由此函数处理的。

如果你想要做的只是重命名文件(把它们留在原来的位置),那么效率不是很高,那么最好用一个shellvariables来完成。

 d_swap() { test $# -eq 2 || return 2 test -e "$1" || return 3 test -e "$2" || return 3 if [ -f "$1" -a -f "$2" ] then mv -b "$1" "$2" && mv "$2"~ "$1" return 0 fi if [ -d "$1" -a -d "$2" ] then mv -T -b "$1" "$2" && mv -T "$2"~ "$1" return 0 fi return 4 } 

该function将重命名文件。 它使用一个临时名称(它在名称前面放一个点“。”),以防文件/目录在同一个目录中,这通常是这种情况。

 d_swapnames() { test $# -eq 2 || return 2 test -e "$1" || return 3 test -e "$2" || return 3 local lname="$(basename "$1")" local rname="$(basename "$2")" ( cd "$(dirname "$1")" && mv -T "$lname" ".${rname}" ) && \ ( cd "$(dirname "$2")" && mv -T "$rname" "$lname" ) && \ ( cd "$(dirname "$1")" && mv -T ".${rname}" "$rname" ) } 

这是更快(没有复制,只是重命名)。 更丑陋。 它会重命名任何东西:文件,目录,pipe道,设备。

这是一个swap脚本与偏执错误检查,以避免不太可能出现故障的情况。

  • 如果有任何操作失败,则报告。
  • 第一个参数的path用于临时path(以避免在文件系统之间移动)
  • 在不太可能的情况下,第二步失败了,第一步就恢复了。

脚本:

 #!/bin/sh if [ -z "$1" ] || [ -z "$2" ]; then echo "Expected 2 file arguments, abort!" exit 1 fi if [ ! -z "$3" ]; then echo "Expected 2 file arguments but found a 3rd, abort!" exit 1 fi if [ ! -f "$1" ]; then echo "File '$1' not found, abort!" exit 1 fi if [ ! -f "$2" ]; then echo "File '$2' not found, abort!" exit 1 fi # avoid moving between drives tmp=$(mktemp --tmpdir=$(dirname $1)) if [ $? -ne 0 ]; then echo "Failed to create temp file, abort!" exit 1 fi # Exit on error, mv $1 $tmp if [ $? -ne 0 ]; then echo "Failed to to first file '$1', abort!" rm $tmp exit 1 fi mv $2 $1 if [ $? -ne 0 ]; then echo "Failed to move first file '$2', abort!" # restore state mv $tmp $1 if [ $? -ne 0 ]; then echo "Failed to move file, (unable to restore) '$1' has been left at '$tmp'!" fi exit 1 fi mv $tmp $2 if [ $? -ne 0 ]; then # this is very unlikely! echo "Failed to move file, (unable to restore) '$1' has been left at '$tmp', '$2' as '$1'!" exit 1 fi