次の現在のフォルダの下にファイルの例があります。
lok.log.1
df.log.6
weq.log.90
vr.log.11
vs.aw.frsd.log.3
ファイル拡張子を1ずつ増やしたいです。
したがって、期待される出力は次のようになります。
lok.log.2
df.log.7
weq.log.91
vr.log.12
vs.aw.frsd.log.4
検索と正規表現を使用してファイル名を変更する方法を提案します。
- 概念は、「.log」を含むすべてのファイルの名前が+1に変更されることです。
答え1
そしてzsh
:
autoload zmv # best in ~/.zshrc
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'
-n
(結果が満足であれば削除してください)
<->
任意の10進数と一致します。(#qnOn)
n
On
ここで:glob修飾子はファイルリストを名前()で逆順に並べ替えるので、名前を変更する前に名前file.log.2
を変更してください。file.log.3
file.log.1
file.log.2
.
定期的なファイル(ただし、隠しファイルの名前を変更したい場合は、-o-nT
GNUを想定するオプションを追加できますmv
)。D
-f
無効にすると、ファイル名が既存のファイルに変更されたときにコマンドから保護が削除され、上記の例が妨げられますfile.log.1
。file.log.2
それでも両方から保護し、foo.log.1
名前foo.log.01
はfoo.log.2
。
再帰的に:
zmv -n -f '(**/)(*.log.)(<->)(#qnOn)' '$1$2$(($3+1))'
またはまたはbash
:sh
ksh
zsh << 'EOF'
autoload zmv
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'
EOF
bash
usingを使用するかどうかにかかわらず、GNUとGNUがzsh
あり、ファイルのリストが大きすぎない場合は、次のことができます。ls
mv
shopt -s failglob
shopt -s extglob
export LC_ALL=C
eval "files=($(
ls --quoting-style=shell-always -rvd -- *.log.+([[:digit:]])))"
for f in "${files[@]}"; do
echo mv -nT -- "$f" "${f%.*}.$((10#${f##*.} + 1))"
done
(満足すれば削除echo
)。
通常のファイルに対してのみGNU bash
、GNU find
、GNU、mv
およびGNUを再帰的に使用します。sort
export LC_ALL=C
while IFS= read -rd '' -u3 file; do
echo mv -nT "$file" "${file%.*}.$((10#${file##*.} + 1))"
done 3< <(
find . -name '.?*' -prune -o -regex '.*\.log\.[0-9]+' -type f -print0 |
sort -rzV)
mv -n
-T
既存のファイルが破損するのを防ぎ、ファイル間のあいまいさを排除するためのGNU拡張。移動するそして引っ越すそれ以外の場合はmv
影響を受けます。ただし、何らかの理由でファイル名が変更されないと、関連する-n
エラーが発生しないことに注意してください。
答え2
rename
ベース - 算術使用を許可する(一部のディストリビューションではこの名前変更ツールの名前を使用しますperl
):prename
perl
rename 's/(log.)([0-9]+)$/$1.($2+1)/e' <files>
find で使用するには、次のようにします。
find <search options> -exec rename 's/(log.)([0-9]+)$/$1.($2+1)/e' {} +
Stéphaneのコメントに従って編集してください。
ソートされていない出力はfind
実際に問題を引き起こす可能性があるため、事前にソートすることをお勧めします。指定された名前パターンに対してバージョン番号付けオプションを使用して、逆方向(!)ソートを使用できます。
find <search parpameters> -print0 |\
sort -rzV |\
xargs -r0 rename 's/(log.)([0-9]+)$/$1.($2+1)/e'