特定パターンのファイルコピー

特定パターンのファイルコピー

ある場所から別の場所にファイルをコピーしようとしています。以下はいくつかの例です。

aaa_bbb_ccc_ddd_cost_code_20140330.gz
aaa_bbb_ccc_ddd_revenue_zone_20140329.gz
aaa_bbb_ccc_ddd_benefit_extract_20140330.csv.gz
aaa_bbb_ccc_ddd_profit_zone_20150509.csv.gz
aaa_bbb_ccc_ddd_loss_zone_20140330.csv
aaa_bbb_ccc_ddd_username.csv.gz

上記のリストからコピーする必要があるファイルは、次の形式でなければなりません。

aaa_bbb_ccc_ddd_cost[or]revenue[or]benefit[or]profit[or]loss_yyyymmdd.csv.gz

これはファイルを意味します。

aaa_bbb_ccc_ddd_loss_zone_20140330.csv
aaa_bbb_ccc_ddd_username.csv.gz

コピーしないでください。

また、変数に割り当てる必要がありますが、次のように試していますが、うまくいかないようです。

FILENAME="egrep 'aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit)_code_[0-9]{8}.csv.gz'"

変数に割り当てる理由は、後で次のようにコードで使用する必要があるためです。

SOURCE_DIR="/temp"
DESTN_DIR="/output"
FILENAME=`egrep 'aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit)_code_[0-9]{8}.csv.gz'`
echo "FILENAME is:" $FILENAME
for SAMPLE_FILE in $(ls "$SOURCE_DIR/$FILENAME")
do
cp $SAMPLE_FILE $DESTN_DIR
done

これを達成する他の方法はありますか?

答え1

Usefind-execそのオプション(ここではGNUを述語findとして使用-regex):

find . -regextype posix-egrep -regex '.*/aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit|loss)_[[:alpha:]]+_[0-9]+\.csv\.gz' -exec mv {} "$DESTN_DIR" \;

メモ:

  • find .find現在のディレクトリから検索するファイルを知らせます。

  • デフォルトでは、GNUはfindemacsスタイルの正規表現を使用します。私はを好む-regextype posix-egrepが、サポートされているおなじみのスタイルに切り替えることができます。

  • 正規表現を使用してファイルを選択します。-regex '.*/aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit|loss)_[[:alpha:]]+_[0-9]+\.csv\.gz'標準プレフィックスaaa_bbb_ccc_ddd_の後に指定された単語の1つ(cost|revenue|benefit|profit|loss)、指定されていない他の単語、_[[:alpha:]]+日付、_[0-9]+最後に希望の拡張子が続きます.csv.gz。これを微調整する必要があるかもしれません。

  • 見つかったすべてのファイルはターゲットディレクトリに移動されます-exec mv {} "$DESTN_DIR" \;。一致するファイルが見つかったら、findこのコマンドを実行して{}ファイルの名前を変更します。これは、ファイル名にスペース、改行、またはその他の読み取れない文字が含まれている場合にも機能します。

正規表現を使用したデフォルト(emacs)スタイル

GNU正規表現のデフォルトスタイルには、findグループ化と代替演算子のいくつかのエスケープが必要です。

find . -regex '.*/aaa_bbb_ccc_ddd_\(cost\|revenue\|benefit\|profit\|loss\)_[[:alpha:]]+_[0-9]+\.csv\.gz' -exec echo mv {} targetdir \;

アップルコンピュータ

Mac OSX バージョンfind(マニュアルページはこちら)はサポートされていますが、-regexサポートされていません-regextype。しかし、正規表現の構文に少しの変更が必要な場合でも驚くことはありません。

IBM AIX 5

IBM AIXバージョンのマニュアルページfindは次のとおりです。ここ。もちろんいいえサポートする-regex

答え2

そしてzsh

setopt extendedglob
source_dir="/temp"
destn_dir="/output"
pattern='aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit)_code_[0-9](#c8).csv.gz'
print -r "pattern is: $pattern"
cp -- $source_dir/$~pattern $destn_dir

ksh93パターンは次のように表現できます。

aaa_bbb_ccc_ddd_@(cost|revenue|benefit|profit)_code_{8}(\d).csv.gz

そしてksh88

aaa_bbb_ccc_ddd_@(cost|revenue|benefit|profit)_code_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv.gz

しかし、拡大するPOSIX互換性が壊れるのを防ぐために、ワイルドカードは変数内で機能できません。

echo @(a)

これはPOSIXに準拠した誤った構文なので、ksh新しいglob演算子にすることができます。しかし:

x='@(a)'
echo $x

POSIXで指定されたものと正確に一致し、現在のディレクトリから呼び出されているファイルでは@(a)なく出力(IFSのデフォルト値を使用)を意味します。aa

evalしたがって、以下を使用する必要があります。

pattern='aaa_bbb_ccc_ddd_@(cost|revenue|benefit|profit)_code_{8}([0-9]).csv.gz'
print -r "pattern is: $pattern"
eval 'cp -- "$source_dir"/'"$pattern"' "$destn_dir"'

答え3

これは1行で実行できます。

find /temp -maxdepth 1 -type f | \
 grep -P 'aaa_bbb_ccc_ddd_(cost|revenue|benefit|profit)_.*[0-9]{8}' | \
 xargs cp -t /output
  • findサブフォルダがないフォルダの内容を一覧表示します。
  • grepあなたのファイル名
  • cpターゲットディレクトリ(-t)にコピーします。

質問は100%明確ではないので、正規表現を調整するだけです。ある文書にはそのような内容があり.csv.gz、ある文書にはあり.csv、ある文書にはあります.gz

答え4

すべての最新のシェルは、デフォルトのglob構文を使用せずに、次のようなものを直接サポートします。

cp aaa_bbb_ccc_ddd_{cost,revenue,benefit,profit,loss}_[0-9]*.csv.gz destination_dir

これは5つの引数に拡張され、各引数は次の形式の球です。..._keyword_<digits>...

2番目の質問に答えるために、各変数を順番に変数に割り当てる方法は次のとおりです。

for FNAME in aaa_bbb_ccc_ddd_{cost,revenue,benefit,profit,loss}_[0-9]*.csv.gz
do
    echo $FNAME
    if [ -e $FNAME ]
    then
        cp $FNAME <destination>
    fi
done

プレゼンスチェック(if [ -e $FNAME ])は、5つのグローブのうちの1つが一致しない場合、グローブをそのまま維持し、エラーメッセージを受け取るために発生します。

関連情報