いくつかのファイルを取得するためにLinuxを実行しているリモートリポジトリにアクセスするWebアプリケーションがあります。問題は、リモートリポジトリに現在300万個のファイルがあるため、一般的なアクセス方法が少し難しいことです。
そのため、作成日、特に名前に基づいてファイルを複数のフォルダに再編成するスクリプトを簡単に使用できるようにする必要があります。このスクリプトを作成し、正常に動作します。もともと意図したとおりに機能しました。しかし、速度が遅すぎて12時間以内に完了できませんでした(12:13:48 to be precise)
。
遅いのは、私が何度も電話をかけたためだと思いますcut
。rev
はい:
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
より速くする方法はありますか?または、ファイル名を切り捨てる別の方法がありますか?sed
ORまたは文字列操作を使用できることはわかっていますが、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
答え2
申請できますsed抽出方法年度値:
year=$(sed -E 's/.*_([0-9]{4})_TY\.pdf/\1/' <<<"$file")