次のファイル番号のリストがあります。
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
03_file_name.log
03_file_name.txt
04_file_name.log
04_file_name.txt
05_file_name.log
05_file_name.txt
03*
すべてのファイルに04*
新しいファイルを挿入したいです。したがって、ワード番号から始めて03
すべてのファイルを移動/名前変更し、前の番号を2ずつ増やす必要があります。したがって、リストは次のようになります。
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
05_file_name.log
05_file_name.txt
06_file_name.log
06_file_name.txt
07_file_name.log
07_file_name.txt
私は次のことを考えています。
bash script.sh 03 02
while03
は、$1
起動するファイル名の番号と追加する番号です02
。$2
入れ子にしてこれを達成しようとしましたが、ループがワード内の指定された番号のファイルのみを実行するようにfor-loop
カウンターを使用する組み合わせを放棄する必要がありました。((++))
答え1
これがあなたが望むものです。一つ:BASHでしか動作しないと思います。
MAXDIGITS
オプションなので、3桁以上を使用する必要がある場合を備えています。使用しない場合は、その行を削除してください。
#!/bin/bash
BOTTOM=$1
SHIFT=$2
MAXDIGITS=0$3
for filename in $(ls -r *.{txt,log}); do
PREFIX=${filename%%_*}
NEWPREFIX=$(expr $PREFIX + $SHIFT)
if [ $PREFIX -ge $BOTTOM ]; then
NEWPREFIX=$(printf %${MAXDIGITS}d $NEWPREFIX)
mv $filename ${NEWPREFIX}_${filename#*_}
fi
done
指示:
./myscript <BOTTOM> <SHIFT> <MAXDIGITS>
### Example:
./miscript 03 02 2 #This means "Start at 03_filename.*, shift the prefixes by 2 and use 2 digits to construct the new prefixes".
同じディレクトリに同じ構文(prefix_filename。{txt、log})に従わない他のファイルがある場合は、フィルタリングする必要があります。そして、プレフィックスとファイル名を区別するために "_"を使用したので、それを変更したらコードを修正する必要があります。
答え2
それは価値があるので、これはbash
2つのものを含む1つのライナーです。プロセスの交換非常に簡単なawk
プロセスです。
$ ls -r -1 *_file_name.{txt,log} # list initial files in reverse order
05_file_name.log
05_file_name.txt
04_file_name.log
03_file_name.txt
03_file_name.log
03_file_name.txt
02_file_name.log
02_file_name.txt
01_file_name.log
01_file_name.txt
$ source <(awk 'BEGIN{FS="_"} $1>2 {prefix=$1+2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}' <(ls -r -1 *_file_name.{log,txt}))
$ ls -1 *_file_name.{txt,log} # list resulting files
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
05_file_name.log
05_file_name.txt
06_file_name.log
06_file_name.txt
07_file_name.log
07_file_name.txt
説明する:
上記の行は右から左に読み取るか、少なくとも「理解」します。
ls -r -1 *_file_name.{log,txt}
処理するすべてのファイルを1列形式で逆順にリストします。
ファイルプレフィックス(記号で示す*
)に数字以外の文字が含まれていると、予期しない/望ましくない結果が発生する可能性があります。これを防ぐには、この手順で処理するファイルをフィルタリングしてください。<(...)
クラフトの交換。ファイル記述子、名前付きパイプと呼ばれる特別な一時ファイルを使用して、以前の結果出力を参照できます。詳しくはman bash
端末に投稿してください。awk
スクリプト:BEGIN{FS="_"}
レコード処理を開始する前に、レコードのフィールド区切り文字を「_」(awkの最初のブロック)に設定してください。awk
2番目のブロックの条件$1>2
:ファイル名のプレフィックスが2より厳密に大きいレコードのみを処理します。prefix=$1+2
awkの「プレフィックス」内部変数を定義します。プレフィックス$1
+ 2と数値的に等しくなります。printf("my_format",var1,var2,...)
改行で区切られた印刷書式設定コマンド。書式設定には、%0.2d
変数「プレフィックス」をawk
2桁の数字で印刷し、必要に応じてゼロを埋める操作が含まれます。出力は次のとおりです
mv -f 05_file_name.log 07_file_name.log
mv -f 05_file_name.txt 07_file_name.txt
mv -f 04_file_name.log 06_file_name.log
mv -f 04_file_name.txt 06_file_name.txt
mv -f 03_file_name.log 05_file_name.log
mv -f 03_file_name.txt 05_file_name.txt
- ソートされた出力を別のファイル(2番目のプロセスの置き換え)として処理し、コマンドを実行するようにします
mv -f ...
。
なぜ再利用するのか気になったらインバウンドまたはアウトバウンドプロセスの交換(POSIXではありません!)inが有利ですbash
。これ例えば。
最終注意事項:
上記のコード行にランタイムパラメータを含め、実行可能なシェルスクリプトにカプセル化するのは簡単です。定義VAR1
してVAR2
割り当てるプロセスから始めてくださいawk
。
$ source <(awk -v VAR1=2 -v VAR2=2 'BEGIN{FS="_"} $1>VAR1 {prefix=$1+VAR2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}' <(ls -r -1 *_file_name.{log,txt}))
実行可能スクリプトからscript.sh
:
$ cat script.sh
#!/usr/bin/bash
if [ "$#" -eq 2 ] ; then
source <(awk -v VAR1=$1 -v VAR2=$2 'BEGIN{FS="_"} $1>VAR1 {prefix=$1+VAR2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}'
<(ls -r -1 *_file_name.{log,txt})
)
exit 0
else
echo " Usage: script.sh VAR1 VAR2.\n Abort execution (exit code 1)."
exit 1
fi
ここではVAR1
、VAR2
OPで定義された意味があります。本番環境でこのスクリプトを使用する必要がある場合は、入力ファイルと変数の値が常に予想されることを確認するために、多くのスキャンと安全装置を追加することをお勧めします。
for
@MarceloCastroのスクリプトは素晴らしいですが、可能であれば避ける傾向があるループに基づいています。for
ループは遅い傾向があります。ループを操作すると、これがわかります。大きいファイル数。
答え3
私はあなたの目標に合わせてこのスクリプトを作成しました。
for files in *.extensions
do
num=$(echo "$files" | awk '{print $1}' | cut -c1-2)
if [ $num -gt 2 ]; then
AS=$((num+2))
temp=$(echo "$files" | cut -c 3-)
mv $files 0$AS"$temp"
fi
done
答え4
そしてzsh
:
$ autoload zmv
$ zmv -n -f '(<3->)(_*)(#qnOn)' '${(l:2::0:)$(($1+2))}$2'
mv -- 05_file_name.txt 07_file_name.txt
mv -- 05_file_name.log 07_file_name.log
mv -- 04_file_name.txt 06_file_name.txt
mv -- 04_file_name.log 06_file_name.log
mv -- 03_file_name.txt 05_file_name.txt
mv -- 03_file_name.log 05_file_name.log
その後、実際にこれを行うには、削除-n
(模擬実行のため)します。
zmv pattern replacement
:zmv
強力な zsh glob および Spread 演算子を活用して複雑なファイル名を変更する自動ロード可能機能です。<x-y>
10進数xとyを一致させます。(#q...)
グローバル予選nOn
:ameのn
数値rdero
(大文字Oに反転)n
。したがって、数字を増やしているので、05...
必要に応じてそれより先に来ます。04...
${(l:n::padding:)expansion}
:l
パッド長延長N使用充填材。したがって、${(l:2::0:)}
使用時の長さは0〜2に保ちます。$(($1+2))
、最初のキャプチャされたグループは2ずつ増加します。$2
:2番目のキャプチャグループ:先行番号の後に続く内容。