数字で名前が付けられたファイルをチェックし、存在する場合は次の連番を使用して新しい名前でコピーする方法

数字で名前が付けられたファイルをチェックし、存在する場合は次の連番を使用して新しい名前でコピーする方法

まず、私の知識不足をお詫びします。これは文字通り私の初めての bash スクリプトであり、Linux の知識は基本的にありません。説明的な回答をいただければ幸いです。方法だけでなく、理由も知りたいです。

私は、1 日に何度も実行しなければならない面倒なプロセスを自動化するスクリプトを作成しようとしています。簡単に言うと、このスクリプトは、特定の要件に基づいて一連のファイルを準備する必要があります。スクリプトは、特定のディレクトリ内にある内容に基づいて、テンプレート ファイルを移動してバージョン番号を割り当てるか、新しいバージョン番号を使用して既存のファイルをコピーする必要があります (たとえば、空の場合は作成し、何かがある場合はコピーします)。

例えば、ファイル名は次のようになります。

YYYYMMDD_##_ユーザー名_テストファイル.json

ここで、## (バージョン番号) は、最初の作成の場合は 01、コピーの場合は 02、その後のコピーの場合は 03 などになります。1 つのディレクトリには、日付とバージョン番号が異なる 10 個以上のファイルや、同じ形式だが testfile.json 以外の末尾を持つ他のファイルが含まれる場合があります。

スクリプトに、ディレクトリ「test」内で、最も高いバージョン番号を持つ testfile.json で終わるファイルを検索させ、見つかった場合は、そのバージョン番号を変数/パラメーターとして抽出し、cp シーケンスに戻すようにさせる方法が見つからないようです。

この時点では、どのコマンドを使用すればよいのかさえわかりません。インターネットでは、grep から awk、リスト作成やソートまで、あらゆるコマンドが提供されているため、頭が混乱してしまいます。

ご協力いただければ幸いです。識別情報はすべて削除しましたので、さらに情報が必要な場合はお知らせください。

答え1

いくつかのステップに分解してみましょう。

次の数字を返す関数を書いてみます。効率を最大化するのではなく、シンプルさを目指します。

ディレクトリ名を付ける必要があります

testfile.jsonファイル名の一部を指定する必要があります

そのディレクトリ内で、その末尾で終わるすべてのファイルを見つける必要があります。

パラメータは $1、$2 などを使用して関数に渡されます。

getnum(){
  ls "$1" | grep "$2\$"
}

区切り文字として を使用し、2 番目のフィールドだけを取り出すには cut を使用します_。(注意: これを実行する場合、grep と cut の代わりに sed を使用します。awk を使用する人もいますが、ここでは単純化を図っています)。

getnum() {
 ls "$1" | grep "$2\$" | cut -d_ -f 2
}

数値順に並べ替えるにはsortを使用します

getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n
}

最初の値だけを取得するにはheadを使用します

 getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1
 }

これをラップしてローカル変数の値を取得します

getnum() {
      local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
}

値がなかった場合は、古い値を 0 に設定します。古い値より 1 つ大きい 2 桁の数字を出力します。

 getnum() {
  local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
  if [ "$oldnum" = "" ]
  then
      oldnum=0
  fi
  printf "%02d\n" $(($oldnum+1))
 }

oldnum が設定されていないことのテストを省略することもできたことに注意してください。その場合、$((oldnum+1))は に展開されます$((+1))。また、 $((${oldnum:-0}+1)) のような式を使用することもできます。詳細については、マニュアルを参照してください。

次のような関数を使うことができます

  dir=somewhere/logs
  ext=testfile.json
  cp template "$dir/$(date +%Y%m%d_)$(getnum "$dir" "$ext")_$USER_$ext"

関連情報