現在、次のスクリプトを作成しています。このコードは、ユーザーがディレクトリに入力したファイル名を探します。スクリプトはまず入力ファイルが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 ]]
意味がありません(そしてthen
afterは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
(最初は見逃しました)。