特定の数値範囲内の奇数を含むすべてのファイルを一覧表示するには?

特定の数値範囲内の奇数を含むすべてのファイルを一覧表示するには?

「file000.txt」から「file999.txt」までのファイルを含むデータセットがあります。

ワイルドカードを使用して、0から500までのすべてのファイルを一覧表示できることを知っています。

ls file{0..500}

奇数を含むすべてのファイルを見つけることができます

ls file*[1,3,5,7,9].txt

私はUnixを初めて使用するので、これら2つのパラメータを組み合わせて、0から500の範囲の奇数を含むすべてのファイルを1行にリストする方法がわかりません。私はこれが迅速な修正であることは間違いないと確信していますが、それを理解することはできません。

答え1

そしてzsh

set -o extendedglob
print -rC1 -- file(<0-500>~^*[13579]).txt

(zsh から) は{0..50}グローバル演算子ではなく、そのファイルが存在するかどうかを拡張する中括弧拡張です。

<0-500>(zshに固有で、まだ他のシェルではコピーされていません)は、0から500までの数字を構成するASCII 10進数シーケンスに一致するglob演算子です。

~~であるとは別にまさか)演算子^です。いいえA~BAであるまさかBA~^BはAですいいえB、だからAとB。

では、bash次のことができます。

shopt -s failglob extglob
printf '%s\n' file*(0)[01234][0123456789][13579].txt

*(0)(kshの拡張glob演算子)は、任意の数の0の場合、0から4までの数字、0から9までの数字、セット13579の数字を期待します。

中括弧拡張は、zshとbash(およびksh931とksh931)に対応するファイルがあるかどうかにかかわらず、yash -o braceexpand1、3、... 499に拡張されます。

printf '%s\n' file{1..499..2}.txt

その他の注意事項:

  • [1,3,5,7,9]と同じで、[13579,]セット内のすべての文字と一致します。あなたは代わりに欲しいです[13579]
  • bash(zshではない)では、[0-9]数百の異なる数値類似文字を一致させるのが一般的です。[0123456789]これらの10個のASCII 10進文字のみを一致させるには、このオプションを使用します。
  • -dこのオプションを渡さずにlsこのオプションに渡されるすべてのファイルfilexxx.txt(シェルの中かっこ拡張またはファイル名の生成(別名ワイルドカード)の結果)はタイプです。目次lsディレクトリの内容を一覧表示します。ただし、ここではシェルから提供されたリストだけが並べ替えられて印刷されるため(ファイルが存在することを確認した後)、デフォルトでは重複し-dます。または、ユーティリティを使用してリストを印刷することもできます。lslsprintprintf

1 {a,b}Braces拡張は70年代後半のcshで行われ、zshは90に{4..10}前半年代を拡張しました(そしてksh93 AFAIKを使用しましたが、zshは最初からこれを行い、通常は別々のパディング演算子があります)。{a-zXYZ}braceccl{1..400..2%04d}{1..400.2}%04d{0001..0400}

答え2

ls file[0-4][0-9][13579].txt奇数で終わるファイルを一覧表示するために使用され、途中で奇数で終わるファイルを一覧表示するls file[0-4][13579][0-9].txtために使用されます。

最後のlsは

 ls file[0-4][0-9][13579].txt file[0-4][13579][0-9].txt file[13][0-9][0-9].txt

file*[1,3,5,7,9].txt一致することに注意してくださいfile100001.txt。これはあなたが望むものではありません。また、括弧内の区切り文字としてカンマを使用しません。[1,3,5,7,9]コンマと同じで、[13579,]コンマとも一致します。

答え3

他の答えが示すように、奇数を見つけるのは簡単です。主に最後の数字を見るだけで十分だからです。

より一般的な場合は、実際には数値を数値として扱う必要があります。これを直接実行するのは難しいですが、たとえば、より大きなコレクションを繰り返して、配列から一致するセットを選択できます。シェル(特にBash)はこの種の操作を実行するのには速すぎませんが、数百または数千のファイルに対してこれを行うことができます。

以下は、7で割ることができる数字のファイルです(Bashでは、前に0がある数字と一致します)。

shopt -s extglob
a=()
for f in file+([0-9]).txt; do 
    n=${f##file*(0)}      # remove leading 'file' and any zeroes
    n=${n%.txt}           # remove tailing '.txt'
    if (( $n % 7 == 0 )); then
        a+=("$f")
    fi
done
printf "%s\n" "${a[@]}"    # or whatever you do with the filenames

または、最初に数字を繰り返すこともできます(Bashなど、前にゼロの数字は表示されません)

a=()
for ((i = 0; i <= 500; i += 7)); do
    f="file${i}.txt"
    if [[ -e "$f" ]]; then
        a+=("$f")
    fi
done
printf "%s\n" "${a[@]}"

あるいは、人工的に矩形の中かっこ拡張を使用して文字列の束を生成して、一致しない文字列を削除するようにシェルに指示することもできます。 ([f]これには文字だけを一致させる必要があるパターンがあります。fおそらく)これは少し無差別で、おそらく効率的ではありませんが、明示的なループを使用しないため、より簡単です。 (Bashは前にゼロの付いた数字も表示しません。)

shopt -s nullglob   # remove non-matching globs
shopt -u failglob
a=([f]ile{0..499..7}.txt)
printf "%s\n" "${a[@]}"

関連情報