ワイルドカードはif文では解釈されません。

ワイルドカードはif文では解釈されません。

現在、次のスクリプトを作成しています。このコードは、ユーザーがディレクトリに入力したファイル名を探します。スクリプトはまず入力ファイルがgzipであることを確認し、そうであれば適切な確認を実行します。ファイルがgzipに圧縮されていない場合、互換性のないファイルテキストが返されます。

私が経験している問題はオンラインです7。ファイル拡張子に関係なく、最終出力と互換性のないファイルが受信されます。

#!/bin/bash
DATE=$(date +%Y-%m-%d)
L0_Report_Generator=("/home/ubuntu/$gzip_file")
echo -n "Enter File Directory:"$gzip_file 
read  $gzip_file
for gzip_file in {$L0_Report_Generator}; do
  if [[ $gzip_file = "test_sub"*"gz" ]] #Check file extension for gzip compression
      then
         gunzip $gzip_file
         echo "file Level 0 QC Check"
         echo ${DATE}
         echo "File Header"
         cat $gzip_file | head
         echo "Total Records"
         cat $gzip_file | wc -l
         echo "File Unique Records Size"
         cat $L0_Report_Generator | sort -u | wc -l
         rm $gzip_file 
    else [[ $gzip_file != "test_sub"*"gz" ]] #If file is anything other than .gz and csv - rort will not run
       then
         echo "incompatible file"
         fi
done

答え1

ifステートメントでワイルドカード式を使用して ".gz"ファイル拡張子を確認するには、次の式を使用できます。

if [[ "${gzip_file}" = *.gz ]]; then echo true; else echo false; fi

次の方法でこれをテストできます。

if [[ "file.gz" = *.gz ]]; then echo true; else echo false; fi

そして:

if [[ "file.txt" = *.gz ]]; then echo true; else echo false; fi

最初の例ではtrue出力を生成し、2番目の例では出力を生成しますfalse

それでは、コードを見てみましょう。 if文には次の条件式があります。

[[ $gzip_file = "test_sub"*"gz" ]]

具体的には、一致パターンの部分文字列として「test_sub」が含まれます。削除してみてください。

答え2

ファイル拡張子の検証について@igalが言ったことに加えて、変数の構文と使い方には多くのエラーがあります。 3行目から始める:

L0_Report_Generator=("/home/ubuntu/$gzip_file")

この変数はgzip_fileまだ設定されていないため、$gzip_fileシェルが拡張されたときに何も置き換えられません。また、括弧はvar=(something)通常の変数ではなく配列を割り当てますが、これは意味がありません。

4行目のecho -n "Enter File Directory:"$gzip_file変数にも同じ問題がありますgzip_file。また、echo -n異なるバージョンのコマンドで他の操作を実行する予測不可能な問題が原因で問題が発生しますecho。改行なしで文字列を印刷するにはより良い方法がありますが、printf "%s" "string to print"この場合はより良いオプションがありますが、これについては後で説明します。

5行目は、read $gzip_fileユーザー入力を変数として読み込むように設計されているように見えますが、gzip_file実際にはそうではありません。シェルで$は変数名の前に付けると、得る変数の現在の値です。ここで欲しい置くだからあなたは以下を維持する必要があります$read gzip_file。しかし、それは私がすることではありません。コマンドの一部としてプロンプト(echo行4)を含めます。read

read -p "Enter File Directory:" gzip_file

いいですね。今6行目です。

for gzip_file in {$L0_Report_Generator}; do

このような設定だと思います。gzip_file 再びread(入力したばかりの値を変更します)。実際にここで設定しようとしていますが、以前のgzip_file変数参照は実際には別の変数でなければなりませんか(多分gzip_dirその逆かもしれません)。

そしてこのin部分も意味がありません。変数を使用しようとしているようですがL0_Report_Generator、この場合は開く中括弧を使用する必要があります。後ろにドル記号。しかしそれも完全に言葉にはなりません。なぜなら${L0_Report_Generator}(これが何をすべきか理解しているなら)、それはディレクトリへのパスにすぎないからです。for ... inディレクトリの内容を繰り返すのではなく、リストを繰り返します。性格、良いfor var in word1 word2 "word 3 which has several spaces in it" word4; do。ディレクトリ内のファイルのリストを取得するには、ワイルドカードを使用する必要があります。たとえば、for var in dir/*; doシェルはワイルドカードを含むファイルパターンを一致するファイルのリストに展開し、各ファイルは単語として扱われ、繰り返されます。それらを。特定の拡張子を持つファイルをパターンに含めて一致を制限することもできますdir/*.gz

DATE他の3つの注意:シェルまたは特定のユーティリティに特別な意味を持つさまざまな大文字の環境変数との競合を避けるために、大文字の変数名(たとえば)を使用しないことをお勧めします。また、予期しない構文解析例外を回避するには、変数を常に二重引用符で囲みます(たとえば"$var"、代わりに使用)。$varそしてelse句にはテストがないので、usingはelse [[ some test ]]意味がありません(そしてthenafterはelse構文エラーです)。

したがって、スクリプトが実行する必要があることを理解している場合は、スクリプトの先頭を次に置き換えることをお勧めします。

#!/bin/bash
date=$(date +%Y-%m-%d)    # Note lowercase variable
read -p "Enter File Directory:" gzip_dir
L0_Report_Generator="/home/ubuntu/$gzip_dir"

for gzip_file in "${L0_Report_Generator}"/*.gz; do

...その後(上記の.gzパターンが必要な場合)、ワイルドカードパターンは.gzファイルのみを一覧表示するため、.gz拡張子をif確認する必要はありません。$gzip_file

もう一つ注意すること:shellcheck.netシェルスクリプトの基本的なエラーを指摘するのに非常に便利です。私が指摘した多くの内容を見逃していますが、迷子になることをキャッチしますthen(最初は見逃しました)。

関連情報