*.pdf ファイルを列挙し、*_book.pdf を除外する

*.pdf ファイルを列挙し、*_book.pdf を除外する

dir 内のすべてのファイルを列挙し、パターンで除外するにはどうすればよいでしょうか。

たとえば、すべての *.pdf から *_book.pdf を除外します。次のように試します。

for $PDF in $(ls *.pdf | grep -v *_book.pdf);
do
   echo "File $PDF"
done

それは良い方法ですか?他の方法はありますか?使用済みもし声明またはその他のもの。

答え1

lsスクリプトでは使用しないでください。

また、ループ内で宣言する変数にはforドル記号を使用しないでください。ドル記号は補間する変数の値。つまり、$PDF「名前が である変数の現在の値PDF」と読みます。

for PDF in *.pdf
do
    case $PDF in
     *_book.pdf) continue;;
    esac
    echo "File $PDF"
done

このcase構文は初心者には怖いかもしれませんが、私はifこのような用途にはこの構文を非常に好みます。しかし、好みに応じて、

    if [[ $PDF =~ _book\.pdf$ ]]; then
        continue
    fi

または速記

    [[ $PDF =~ _book\.pdf$ ]] && continue

caseshPOSIXや古き良きオリジナルの Bourneにも移植可能であるという追加の利点がありますsh

のパターンはcaseglob ですが、 では正規表現が使用されていることに注意してください (したがって、の前に は[[ $variable =~ regex ]]存在しないはずです)。*_book

答え2

shopt -s extglob(システムのデフォルトになっている場合もありますが、そうでない場合は設定してください)を使用すると、拡張マッチングを使用でき、これには否定一致パターンが含まれます。

# Directry contents
>ls -1
1_book_not.pdf
1_book.pdf
1.pdf
1.txt

# With negative match
>ls -1 !(*_book).pdf
1_book_not.pdf
1.pdf

答え3

式に若干の構文エラーがありましたfor。代わりに次の文を試してください。

for PDF in $(ls *.pdf | grep -v *_book.pdf);
do
   echo "File $PDF"
done

これはうまく機能するようです。

答え4

別のオプションとしては以下を使用しますfind:

find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'

たとえば、次の 4 つのファイルを含むディレクトリを考えます。

$ ls
a_book.pdf  book.txt  nook.pdf  not_book1.pdf

次に、コマンドを実行します。

$ find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'
./not_book1.pdf
./nook.pdf

使い方

  • find .find に現在のディレクトリで検索を開始するように指示します。

  • -maxdepth 1find にサブディレクトリをスキップするように指示します。

  • -name '*.pdf'find に、名前が if で終わるファイルを検索するように指示します.pdf

  • ! -name '*_book.pdf'は、名前が で終わるファイルを出力から除外するように finds に指示します_book.pdf

関連情報