同じ名前の既存のファイルがある場合、ファイルに新しい名前を生成するにはどうすればよいですか?デスクトップ環境では、ファイル名の最後に番号を追加して新しい名前を生成しますが、これはコマンドラインからどのように実行できますか?
BusyboxでAndroidオペレーティングシステムを使用しています。
mktemp
か?
mktemp
と機能しません。
同じ名前の既存のファイルがある場合、ファイルに新しい名前を生成するにはどうすればよいですか?デスクトップ環境では、ファイル名の最後に番号を追加して新しい名前を生成しますが、これはコマンドラインからどのように実行できますか?
BusyboxでAndroidオペレーティングシステムを使用しています。
mktemp
か?
mktemp
と機能しません。
回答:
あなたがPOSIXシェルを持っていると仮定すると、これを行うことができます:
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の前のすべて)、拡張(最終的なの後の.
すべて)、カウント(存在する場合、最終的なの後のプレフィックス内の何か)を抽出し-
ます。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
ステートメントのin を好きなように変更します。/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(jelly bean 4.2.1)シェルでもテストしましたが、そこで動作します。ただし、Androidでは、指示どおりにシバンを変更または実行するsh dotmv
必要があります。ルート化されたデバイスがない限り、とにかくスクリプトを実行可能にする方法がないためです。シバンを変更すると、使用できるようになります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を備えたその他の完全な手続き型言語で実装できます。