1

生のカメラファイルを移動するMacでシェルスクリプトを作成しようとしています。これらのファイルには、非常に具体的な名前を付ける必要があります。ファイル名をチェックするための正規表現がありますが、正しく機能させることができませんでした。正しく機能するのは、生ファイルを含むフォルダー名を特定のフォルダー内で検索し、ファイルのリストを取得することです。

私もエラーチェックを試みています。if ステートメントを使用してファイル名をチェックしようとしています。

ファイルの名前が正しいかどうかを確認するための if ステートメントを書くのに助けが必要です。

この時点で完全に立ち往生しているので、助けていただければ幸いです。

これが私がこれまでに持っているものです:

#!/bin/bash

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.(EIP)"

#folder of files to check
folder_files="$(ls -d *)"

#just get a list of everything .EIP
FILES_LIST="$(ls *.EIP)"

for file in $FILES_LIST; do
#something with $file

echo $file

#where im having the trouble 
If (grep or find based on $product)
then

    #move files, create log

else

    #move files to an error folder for renaming

fi

done
exit 0
4

2 に答える 2

2

中かっこは、基本正規表現 (BRE) 構文ではなく、拡張正規拡張 (ERE) 構文の一部であるため、「egrep」を使用する必要があります。また、正規表現から括弧を自由に削除しました。末尾が で終わるファイルを探していることがわかった.EIPので、次のようになります。

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.EIP"

$IFSまた、変数は FOR ループでフィールド セパレータを決定するために使用されるため、変更する必要があります。デフォルトでは、フィールド区切り文字はスペース文字に設定されています。これは、フィールド区切り文字が文字列の一部である可能性がある文字列 (つまり、ファイル名にスペースが含まれている場合) ではうまく機能しません。IFS の現在の値を変数に保存し、IFS を設定します。

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

完了したら、IFS を元の値に戻します。

IFS=$SAVEIFS

ここで、ファイル名を egrep にパイプし、正規表現を使用してフィルタリングし、 と の両方stdoutstderrにリダイレクトし/dev/nullます。変数は、$?egrep が一致を返したかどうかを知らせてくれます。

echo $file | egrep $product &>/dev/null
if [ $? -eq 0 ]; then 
  echo "$file - acceptable"
else 
  echo "$file - not acceptable"
fi

完全なスクリプトは次のようになります (マウンテン ライオンでテスト済み)。

#!/bin/bash 

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.EIP"

FILES_LIST="$(ls *.EIP)"

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

for file in $FILES_LIST; do
  echo $file | egrep $product &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - acceptable"
    #move files, create log
  else 
    echo "$file - not acceptable"
    #move files to an error folder for renaming
  fi
done

IFS=$SAVEIFS

exit 0

以下に示すように、ステートメントの複数のブロックと最後に 1 つの条件のみを使用して、 N 個の命名規則への準拠を確認できることに注意してください。ifelse

for file in $FILES_LIST; do

  echo $file | egrep $regex1 &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regex1"
    #move files, create log
    continue
  fi

  echo $file | egrep $regex2 &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regex2"
    #move files, create log
    continue
  fi

  echo $file | egrep $regexN &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regexN"
    #move files, create log
  else 
    echo "$file - not acceptable"
    #move files to an error folder for renaming
  fi
done

continueを使用してループの反復を再開し、ファイルごとに 1 つのアクションのみを実行できることに注意してくださいfor(ファイル名は複数の命名規則に準拠していると考えてください)。

于 2013-08-20T22:46:23.770 に答える
1

macosx が gnu find を使用していることは確かではありませんが、使用していることは間違いありません。

find . -regextype posix-egrep -ireg ${myregex} -print

一致するファイル名にはパス全体が含まれるため、正規表現を ^./ で開始し、$ で終了する必要があります。

if ではなく、全体を 2 つの xargs として書きたいと思います。

# first move the good stuff to its destination
find . -type f -regextype posix-egrep -ireg ${myregex} -print0 | xargs -I{} -0 mv {} ../good-dir/
# anything remaining is bad
find . -type f -print0 | xargs -I{} -0 sh -c 'echo "bad file name: {}" > /var/log/whatever.log; mv {} ../bad-dir/'
于 2013-08-20T21:24:42.930 に答える