If,then...fi コマンドを使用して、ユーザーが入力したファイル形式が正しいことを確認する方法は? [コピー]

If,then...fi コマンドを使用して、ユーザーが入力したファイル形式が正しいことを確認する方法は? [コピー]

続行する前に、ユーザーに正しいスクリプトファイル形式を入力したかどうかを知らせる非常に基本的なbashスクリプトを作成しようとしています。たとえば、

echo "Input .txt file here:"
read file
if $file = *.txt
    then 
    echo "File is in correct format."
    else
    echo "File is not in correct format. Please recheck your file."
    fi

これには何を使用できますか?

以下のコマンドは機能せず、実際に目的の操作を実行するのではなく、「その他」のみを報告します。

$file = *.txt

答え1

もちろん、ファイル拡張子だけではファイル形式ではありません。これは誰でも簡単な操作で変更できるテキストです。

mv image.png word.txt

つまり、この場合、単に次のbasenameコマンドを使用できます。

base=`basename "$file" .txt`
if test "$base" != "$file"
then
    echo "Success!"
else
    echo "Wrong extension..."
fi

答え2

次のスクリプトを試すことができます。

if [ ".$(echo "$file"| cut -d. -f2)" == ".txt" ]
then
echo "File is in correct format."
else
echo "File is not in correct format. Please recheck your file."
fi

.ファイル名に複数のドット(ドット)がある場合は、次のコマンドを使用できます。

if [ ".$(echo "$file"| awk -F. '{print $NF}')" == ".txt" ]

答え3

いいですね。何をしたいのかを見てみましょう。最初に知っておくべきことは、ファイル名が ""であることを確認したくないのですが、ファイル名が " "であることを確認したい*.txtということです。パターンマッチ*.txt。」また、Unixスクリプトではさまざまな種類のパターンに触れていますが、最も一般的なのはワイルドカード(または「glob」)パターンと正規表現(正規表現構文のバージョンが異なる)です。ここにはグローバルパターンがあります。

したがって、グローバルパターンマッチングを実行するツールが必要です。 (もちろん、別の構文でパターンを書き直すことも、拡張子を確認するためにまったく異なるアプローチを取ることもできますが、今はglobパターンの一致に固執します。)

次に、ステートメントで使用しますif。文の条件(およびifその間の内容)は次のとおりです。ifthen注文する(または少なくともコマンドのようなもの)。このifステートメントは、コマンドが成功したか失敗したかによって異なります。if最も一般的に使用されるコマンドの1つは、次[のステートメントです。

if [ "$file" = "*.txt" ]; then

シェル構文や奇妙な括弧のように見えますが、[そうではありません。これは通常のコマンド(ほとんど同じtest)です。ただし、これは最後の引数が「]」(実際に閉じた角かっこではなく通常のコマンド引数である)でなければならず、残りの引数を論理式に解析する一般的なコマンドです。man [構文を参照してください。また"$file"、両方に二重引用符を入れており"*.txt"(一般的なコマンド引数として)、ファイル名はトークン化の対象となり、両方ともワイルドカード拡張の対象となり、式構文に混乱を招く可能性があるからです。

ただし、[パターンマッチングは行われません。文字列と数値(整数)の比較はできますが、パターンマッチングはできません。したがって、私たちは他の場所を見なければなりません。

bash(またはzshまたはkshを使用していますが、いいえダッシュやその他のより基本的なシェル)、これとは異なり[[ ]][はい通常のコマンドの代わりにシェル構文は本質的に[できる=演算子とパターンマッチングもし右側は引用しないままにしておきます。つまり、リテラル文字列比較を実行します。

if [[ "$file" = "*.txt" ]]; then

グローバルモードパッチが実行されます。

if [[ "$file" = *.txt ]]; then

(実際には、これらの項目を二重引用符で囲む必要はありませんが、変数参照を自動的に二重引用符$fileで囲むことをお勧めします。二重引用符を使用することはほとんど常に安全であり、一般に引用符を解放するのは安全ではなく、例外を覚えていますより簡単だからです。

したがって、最後のコマンドが可能な答えです。もしサポートされているシェルを使用しています[[ ]](つまり、bash shebangを使用するか、通常のshを使用しない場合#!/bin/bash#!/usr/bin/env bash

plain を使用する場合は、sh規則を少し変更する必要があります。一般的なPOSIXシェルでワイルドカードパターンマッチングを実行する最も簡単な方法はをcase使用することですif。なぜなら、これはワイルドカードパターンマッチングcaseのために誕生したからです。

case "$file" in
    *.txt )
        echo "File is in correct format." ;;

    * )
        "File is not in correct format. Please recheck your file." ;;
esac

パターン*(以前のパターンと一致しないすべての項目と一致)は、ステートメントの句のelseように機能しますif。また、)各パターンと一致するコマンド間、および;;各パターンコマンドの終わりに構文に慣れるまでに時間がかかります。

「Globパターンを一致させたい」から「ファイル名が '.txt'で終わるかどうかを確認したい」に切り替えると、他のオプションがあります。ファイル名変数を拡張するときに修飾子を使用してこれを達成するためのいくつかの(POSIX標準)方法があります。たとえば、${var%pattern}一致は変数値の末尾から削除されます(patternもし一致します)。したがって、標準的な方法は、ファイル名の末尾から「.txt」を削除して変更されていることを確認することです。その場合、「.txt」は一致し、そうでなければ一致しません。このように:

if [ "$file" != "${file%.txt}" ]; then

!=「.txt」が最後に正常に削除された場合にのみ文字列が異なるため、等しくないテスト()を使用します。

最後の「.」を削除することもできます。ファイル名に${file##*.}(残りが「txt」であることを確認するために)ここに問題がある場合は、ファイル名「txt」が一致すると思います。こんな。

関連情報