「カット」と「rev」を使用する現在の方法よりも、ファイル名から年を抽出して年ベースのディレクトリに移動するより速い方法は何ですか?

「カット」と「rev」を使用する現在の方法よりも、ファイル名から年を抽出して年ベースのディレクトリに移動するより速い方法は何ですか?

いくつかのファイルを取得するためにLinuxを実行しているリモートリポジトリにアクセスするWebアプリケーションがあります。問題は、リモートリポジトリに現在300万個のファイルがあるため、一般的なアクセス方法が少し難しいことです。

そのため、作成日、特に名前に基づいてファイルを複数のフォルダに再編成するスクリプトを簡単に使用できるようにする必要があります。このスクリプトを作成し、正常に動作します。もともと意図したとおりに機能しました。しかし、速度が遅すぎて12時間以内に完了できませんでした(12:13:48 to be precise)

遅いのは、私が何度も電話をかけたためだと思いますcutrev


はい:

lsコマンドとともに for ループを使用してファイル名をインポートし、各ファイルの親ディレクトリをインポートし、親ディレクトリに基づいて正しい年をインポートできます。

 case "$parent" in
                ( "Type1" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev );;

                ( "Type2" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev);;

                ( "Type3" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;

                ( "Type4" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;

                ( "Type5" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;
                esac

~のためタイプ1ファイル数:

the file==>MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf

逆剪断を実行するには、年を取得する必要があります。

year=$(echo "$file" | rev | cut -d '_' -f 2 | rev );;

~のためタイプ2ファイル数:

the file==>MY_AMAZING_FILE_THAT_IMADE_IN_YEAR_WITH_TY.pdf 

など...

mvその後、ファイルを自由に使用できます。mv $file /some/path/destination/$year/$parent

しかし、これは最も簡単な例です。一部のファイルははるかに複雑なため、1つの情報を取得するには4つの作業を行う必要があります1 echo , 2rev and 1echo

スクリプトが実行されると、私の速度はスクリプトを実行して50 files/sec to 100 files\s この情報を取得します。wc-l output.txt


より速くする方法はありますか?または、ファイル名を切り捨てる別の方法がありますか?sedORまたは文字列操作を使用できることはわかっていますが、awk実際にどのように使用しているのかわかりません。

ベストアンサー1

外部ユーティリティを使用せずにYEARファイル名の一部を取得するには、次の手順を実行します。MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf

name='MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf'

year=${name%_*}    # remove everything after the last '_'
year=${year##*_}   # remove everything up to the last (remaining) '_'

質問を更新した後:

以下で、PDFファイルをファイル名に年が含まれ、ファイルが配置されている元のディレクトリのデフォルト名であるディレクトリtopdirに移動します。/some/path/destination/<year>/<parent><year><parent>

find topdir -type f -name '*.pdf' -exec bash ./movefiles.sh {} +

movefiles.sh現在のディレクトリにシェルスクリプトがありますか?

#!/bin/bash

destdir='/some/path/destination'

for name; do
    # get basename of directory
    parent=${name%/*}
    parent=${parent##*/}

    # get the year from the filename:
    #  - Pattern:  _YYYY_         (in the middle somewhere)
    #  - Pattern:  _YYYYMMDD.pdf  (at end)
    if [[ "$name" =~ _([0-9]{4})_ ]] ||
       [[ "$name" =~ _([0-9]{4})[0-9]{4}\.pdf$ ]]; then
        year="${BASH_REMATCH[1]}"
    else
        printf 'No year in filename "%s"\n' "$name" >&2
        continue
    fi

    # make destination directory if needed
    # (remove echo when you have tested this at least once)
    if [ ! -d "$destdir/$year/$parent" ]; then
        echo mkdir -p "$destdir/$year/$parent"
    fi

    # move file
    # (remove echo when you have tested this at least once)
    echo mv "$name" "$destdir/$year/$parent"
done

おすすめ記事