如果已有同名文件,该如何为该文件生成新名称?在桌面环境中,会在文件名的末尾附加一个数字来生成一个新名称,但是如何从命令行完成呢?
我正在将Busybox与Android操作系统配合使用。
mktemp
吗?
mktemp
将不起作用。
如果已有同名文件,该如何为该文件生成新名称?在桌面环境中,会在文件名的末尾附加一个数字来生成一个新名称,但是如何从命令行完成呢?
我正在将Busybox与Android操作系统配合使用。
mktemp
吗?
mktemp
将不起作用。
Answers:
假设您拥有POSIX Shell,则可以执行以下操作:
mv() {
eval "DEST=\${$#}" #The destination is the last positional parameter
if [ -e "$DEST" ] && ! [ -d "$DEST" ];then
PREFIX=${DEST%.*}
COUNT=1
EXT=${DEST##*.}
args= i=1
while [ $i -lt $# ]; do args="$args \"\${$i}\"" i=$((i+1)); done
DEST="$NAME-"$(printf "%03d" $COUNT)".$EXT"
while [ -e "$DEST" ];do
COUNT=$((COUNT+1))
DEST="$NAME-"$(printf "%03d" $COUNT)".$EXT"
done
eval "command mv $args \"\$DEST\""
else
command mv "$@"
fi
}
如何使用
这是一个函数,因此将其保存在您的计算机中,~/.bashrc
然后像平常一样调用它mv
。
这是做什么的
mv
可执行文件的路径存储在MV
变量中DEST
DEST
存在并且不是目录,则此函数假定您的重命名试图破坏文件.
,标记扩展名),扩展名(在final后面的任何内容.
),计数(如果有的话;在final后面的前缀中的任何内容-
)。mv a.txt b.txt
是它将首先尝试mv a.txt b-001.txt
。下一个mv
调用也必须是函数本身,因为如果b-001.txt
还存在,我们希望继续增加计数器,直到找到不存在的新文件名。mv
使用原始参数调用原始可执行文件。注意事项
foo-001.txt
将移至foo-001-001.txt
。笔记
3
请将printf
语句中的更改为所需的内容。/tmp
一个存在的目录,并称/bin/mv file1 /tmp
我看不出问题出在哪里。
我通常使用该工具mktemp
来创建可靠的临时文件。它默认为创建文件,但也可以通过其-d
开关来创建目录。
您可以通过以下方法为当前目录中的文件创建一些临时名称。
$ mktemp somefile.XXXXX
somefile.kiDad
$ mktemp somefile.XXXX
somefile.MrSW
$ mktemp someotherfile.XXXXXXXXXXX
someotherfile.Um4aXKrt3lv
这将为您创建文件。
mktemp
在android上没有,但是无论如何我还是+1,因为这是一个很好的问题的很好的答案,U&L明智的选择。
/system/bin/sh
并且似乎是sh
兼容的-像if [ -w $file ]
工作一样的结构,mv
并且rename
可用-因此仅使用内置脚本执行此操作的脚本应该在那里工作。
这是约瑟夫·R脚本的替代品,没有任何警告!它将在路径名后附加一个数字后缀(该路径可以是目录或文件),增加后缀值直到找到一个不存在的后缀。其他实用程序(例如)logrotate
使用类似的模式,但是轮换所有现有副本,以便新副本的后缀始终为“ 0”。由于从这个意义上讲这不是轮换,所以我将其称为dotmv
。只要记住那file.0
将是最旧的副本。
例如:
dotmv somefile.txt
重命名somefile.txt
somefile.txt.0
,除非后者存在,否则将重命名,somefile.txt.1
依此类推。您可以列出多个文件(dotmv this that "the other thing"
等),所有文件都将被点移动。
我相信这是POSIX兼容的-它可以set -o posix
在bash上运行(但这是一个可疑的测试)。我还使用android(软糖豆4.2.1)外壳进行了测试,并且在该外壳上可以正常工作。但是,在android上,您将需要按指示更改shebang或运行它sh dotmv
-无论如何,除非您拥有root用户的设备,否则您将一直这样做,因为否则无法使脚本可执行。更改shebang将使您可以使用exec dotmv
。
#!/bin/sh
# On android change that to /system/bin/sh.
# Validate arguments
if [ $# -lt 1 ]; then
echo "A list of one or more paths is required."
exit 1
fi
# Checks if a path exists and can be moved.
checkPath () {
if [ ! -e "$1" ]; then
echo "'$1' does not exist."
return 1;
fi
if [ ! -w "$1" ]; then
echo "Cannot move '$1', permission denied."
return 1;
fi
return 0;
}
# Finds a new path with numerical suffix.
getName () {
suf=0;
while [ -e "$1.$suf" ]
do let suf+=1
done
Dest=$1.$suf
}
# Loop through arguments -- use quotes to allow spaces in paths.
while (($#)); do
Src=$1
Dest=$1
shift
checkPath "$Src"
if [ $? -eq 0 ]; then
getName "$Src"
mv "$Src" "$Dest"
fi
done
希望这里的逻辑很简单。这可以用python,C或任何其他具有文件I / O的完整的过程语言来实现。