2017-09-21 13 views
0

引用符でフォルダを扱うことができない見つけるには:シェルスクリプト:私は、次のシェルスクリプトで問題に直面しています

#!/bin/bash 

searchPattern=".*\/.*\.abc|.*\/.*\.xyz|.*\/.*\.[0-9]{3}" 
subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0 | sed 's/.*/"&"/') 

echo "subFolders: $subFolders" 

# iterate through subfolders 
for thisFolder in $subFolders 
do 
    echo "The current subfolder is: $thisFolder" 

    find -E $thisFolder -type f -iregex $searchPattern -maxdepth 1 -print0 | xargs -0 7z a -mx=9 -uz1 -x!.DS_Store ${thisFolder}/${thisFolder}_data.7z 
done 

その背後にある考え方は終了.abc、.xyzというとでファイルタイプをアーカイブすることです。 000〜.999をサブフォルダごとに1つの7zアーカイブに保存します。しかし、私はスペースを含むフォルダを扱うことはできません。上記のように、私は、スクリプトを実行すると、私はいつも次のエラーを取得する:

find: "20130117_test": No such file or directory 

私は

subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0) 

スクリプトのような作品に変えライン

subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0 | sed 's/.*/"&"/') 

でスクリプトを実行した場合魅力的ですが、スペースを含むフォルダには当てはまりません。中

find -E "20130117_test" -type f -iregex ".*\/.*\.abc|.*\/.*\.xyz|.*\/.*\.[0-9]{3}" -maxdepth 1 -print0 | xargs -0 7z a -mx=9 -uz1 -x!.DS_Store "20130117_test"/"20130117_test"_data.7z 

私は問題が何らかの形で(引用符で)フォルダのリストの保存に関連している知っている:

不思議なことに、私はシェルで直接次の行を実行すると、予想通り、それは動作します変数のサブフォルダが、私は単純にそれを正しく動作させるための方法を見つけることができません。

私はシェルで、より高度な誰かがここで私を助けることができると思います。一般的に

+0

内側(GNU)の出力にループに標準的な方法がないフォルダを作成しないように7Zに指示 'find'である:' IFSは= -r -d 'を読んでいる間' ファイル名; "$ filename"で何か... ...; done <<(find .... -print0) 'となります。 [ParsingLs](http://mywiki.wooledge.org/ParsingLs)を参照してください(このページを読んで、このサイトで利用可能なすべての情報を読んでください)。 –

+0

@gniourf_gniourfアドバイスありがとう! – zionlion

+0

リテラル引用符(あなたのスクリプトが処理するデータの引用符)は、構文引用符(スクリプト自体の引用符)を代用することはできません。 [BashFAQ#50](http://mywiki.wooledge.org/BashFAQ/050)を参照してください。 –

答えて

1

、あなたはファイル名のリストを生成する試みでfindを使用しないでください。あなたは特にあなたが試みている方法で引用されたリストを構築することはできません。引用符でパラメータ値と引用符周りのパラメータ展開との間に違いがあります。私は私がしたい正確に何している、次のコードを生成することができましたgniourf_gniourfとchepnerからの入力を組み合わせる

shopt -s nullglob 

subFolders=(
    *201[0-4][0-1][0-9]* 
    *20150[1-6]* 
) 
for thisFolder in "${subFolders[@]}"; do 
    echo "The current subfolder is: $thisFolder" 
    to_archive=(
    */*.abc 
    */*.xyz 
    */*.[0-9][0-9][0-9] 
) 
    7z a -mx9 -uz1 -x!.DS_Store "$thisFolder/$thisFolder_data.7z" "${to_archive[@]}" 
done 
+0

提案に感謝します。しかし、次のように試してみてください: 'subFolders =(* 201 [0-4] [0-1] [0-9] * * 20150 [1-6] *); "$ {subFolders [@]}"のthisFolderのために;行う; echo "現在のサブフォルダは$ thisFolder"; 20130208_test現在のサブフォルダは:20130208_test with spaces'です。さらに、現在のサブフォルダは:* 20150 [1-6] *を取得しています。 '。何が問題なのか考えていますか? – zionlion

+1

スペースを正確に扱うように見えます。 2番目の問題として、 '* 20150 [1-6] *'にマッチするフォルダはありません。 'shopt -s nullglob'を使って、一致しないパターンがリテラル文字列の代わりに無視されるようにしてください。 – chepner

+0

'shopt -s nullglob'オプションは意味があります。なぜなら私のテストフォルダでは、実際に' * 20150 [1-6] * 'のようなもので始まるサブフォルダがないからです。また、スペースは今すぐうまく処理されます。私は、以前のテストから間違ったフォルダが作成されたことに気がつきました( "20130208_test"は存在しないはずですが、スペースは "20130208_test"のみ)。しかし、現時点ではディレクトリだけでなくファイルも "subFolders"にリストされています。サブフォルダにのみフォルダを含めるにはどうすればよいですか? – zionlion

0

:ここでは、特に、あなただけの単純なパターンを使用することができます。

#!/bin/bash 

shopt -s nullglob 

find -E "$PWD" -type d -maxdepth 1 -regex ".*201[0-5][0-1][0-9].*" -print0 | while IFS="" read -r -d "" thisFolder ; do 
    echo "The current folder is: $thisFolder" 
    to_archive=("$thisFolder"/*.[Aa][Bb][Cc] "$thisFolder"/*.[Xx][Yy][Zz] "$thisFolder"/*.[0-9][0-9][0-9]) 

    if [ ${#to_archive[@]} != 0 ] 
    then 
    7z a -mx=9 -uz1 -x!.DS_Store "$thisFolder"/"${thisFolder##*/}"_data.7z "${to_archive[@]}" && rm "${to_archive[@]}" 
    fi 
done 

shopt -s nullglob正規表現パターンに一致するディレクトリの非マッチング文字に向かって無知に

find...検索を導き、ヌル分離器を使用してwhileループに一致する各フォルダストリーム。

whileループ内では、可変拡大を$thisFolderとすると安全に引用符を付けることができ、したがって可能なスペースに対処します。絶対パスの代わりに相対パスを使用して

アーカイブ

関連する問題