スクリプト/コマンドラインでアルファベット順などに基づいて現在のディレクトリからファイルのサブ範囲を選択する方法は?

スクリプト/コマンドラインでアルファベット順などに基づいて現在のディレクトリからファイルのサブ範囲を選択する方法は?

ファイルマネージャでは、通常、ファイルを選択し、他のShiftファイルを長く選択できます。その間のすべてのファイルが選択されます。

私はしたいbash/zshこれと同等である。

例:2つのファイル名を指定したいと思います。各ファイル名は中央にあります(アルファベット順 -ls出力方式)。

そして他のワイルドカードオプションを知っていますが、名前が? {} *非常に混乱しているファイルに使用できることを願っています。

たとえば、与えられたファイル

$ ls
aoeitoae.txt
oaeistn.txt
oaie.txt
paeoai.txt
sotaoe.txt

次のコマンドを実行して次のようにしますrm aoeitoae.txt-oaie.txt

$ ls
paeoai.txt
sotaoe.txt

この目標をどのように達成できますか?

ベストアンサー1

この答えは主にzshについてです。ほとんどの操作はbashでは簡単にはできません。

多くの一般的な状況で使用できます。ワイルドカード。特に:

  • すべてが付属固定プレフィックス:foo-*
  • すべてが付属固定プレフィックスの後に範囲内の他の文字が続きます。:(、、、をfoo[b-m]*含むが、または除く)foobarfoodfoomz1fooarfoon
  • 特定の範囲内の数:(IMG-<7-42>.*含むIMG-8.PNGIMG-0042.JPG除くIMG-77.JPG

そしてグローバル予選、識別する簡単な方法があります。範囲ですが、数が必要です:ファイルが何であれ、リストされてfoo*([1,3])いる最初の3つのファイルと一致しますfoo*(3つ未満の場合はすべてのファイルと一致します)。foo*(om[1,3])これは、で始まる名前の一致などのソートが完了した後に発生しますfoo

zshに数字を調べるように依頼できます。 2つのステップで行います。まず、すべての一致を配列に配置し、次を使用します。下付き文字記号 i(ワイルドカードの一致を防ぐI場合e):要素間の配列部分(含まれて$a[$a[(i)foo],$a[(I)bar]]いる)または存在しない場合は空です。$afoobarfoobar

a=(*.txt(oL))
# List the files that appear between small.txt and large.txt in a listing by size.
# Note that files that have the same size as one of the bounds may or may not be included.
echo $a[$a[(I)small.txt],$a[(I)large.txt]]

だからこれは実装する関数です。質問の要件を完全に満たしています。(正確な構文を除いてこれを行うことはできません):

# Usage: select_range FROM TO WILDCARD_PATTERN
# Sets the array $s to the files matching PATTERN from FROM to TO inclusive.
function select_range {
  if (($# < 2)); then
    echo >&2 "select_range: missing range arguments"
    return 120
  fi
  local from=$1 to=$2
  shift 2
  from=$@[(ie)$from]
  if ((from == 0)); then
    echo >&2 "select_range: not matched: $from"
  fi
  to=$@[(Ie)$to]
  if ((to == 0)); then
    echo >&2 "select_range: not matched: $from"
  fi
  s=($@[$from,$to])
}

使用法:select_range aoeitoae.txt oaie.txt * && rm $s

globe修飾子を使用すると、任意のコードを書いて結果をフィルタリングできますが、少し扱いに​​くくなり始めました。複雑なケースでは、引用は難しいかもしれません。簡略化のために'区切り記号(バックスラッシュとして引用する必要があります)として使用し、フィルタコードを一重引用符で囲んでパターンを次に示しますfoo-*(e\''code goes here'\')。 (引用が複雑すぎる場合は、関数を作成して修飾子を使用してください+。)フィルタリングaoeitoae.txt前とフィルタリング前のファイルoaie.txt アルファベット順*(e\''! [[ $REPLY < aoeitoae.txt || $REPLY > oaie.txt ]]'\')

フィルタで実行された比較は、必ずしもワイルドカード拡張と同じ順序を使用するわけではありません。たとえば、thanks修飾子はfoo-*(n)前にリストされていますが、文字列比較ではfoo-9foo-10n[[ foo-9 > foo-10 ]]ホームフレーズ整数部分文字列の数値比較に似た>演算子です。一つ作りたいなら文字列と数値でソートされた整数部分の比較、あなたはそれを使用することができますn パラメータ拡張フラグ配列を並べ替え、中間に一致する名前が保持されていることを確認します。 、、、、...*(ne\''a=(b11r $REPLY f10o); [[ $a[2] == "${${(@n)a}[2]}" ]]'\'))は含まれていますが、、、...は含まれていません。b101rb11sd1f02ob9rf011

日付別にファイルを一致させる場合は、条件を使用できます(ファイルは独自のファイル-ntよりも最新ではありません)。*(ome\''! [[ $REPLY -ot from || $REPLY -nt to ]]'\')間に修正されたファイルの修正時間fromとの修正時間to(含む)です。

おすすめ記事