ファイル名に基づいてフォルダを作成する

ファイル名に基づいてフォルダを作成する

.pngたとえば、多くのファイルを含むフォルダがあります。

Jeff Smith 1.png
Jeff Donald 1.png
Jeff Donald 2.png
Jeff Smith 2.png
Jeff Roberts.png
Kyle Reds.png
Kyle Reds 1.png
Kyle Blues 1.png
Kyle Blues 2.png
Kyle Person.png
etc 
etc

各識別名のフォルダを生成するbashスクリプトをどのように作成しますか?

上記の例では、次のフォルダを取得します。

Jeff Smith
Jeff Donald
Kyle Reds
Kyle Blues
Kyle Person 
etc

私はbash(そして一般的なコーディング)に初めて触れました。これの助けを受けたいです。

ありがとう

答え1

そしてzsh

#! /bin/zsh -
() { mkdir -p -- ${(u)argv%%( <->|).png}; } *.png

どこ:

  • () { code; } arguments.pngは、現在ディレクトリ($argvまたは経由$@でアクセス可能code)に隠されていないファイルのリストを引数として使用する匿名関数です。
  • <->zsh glob演算子ですべての10進数シーケンスと一致します(<first-last>指定または指定されていませんfirstlast
  • ${(u)array-expansion}配列拡張の一意の要素に展開します(重複排除)。
  • ${array%%pattern}配列の要素に展開し、最後から一致する最も長い文字列を削除しますpattern

" <digits>"したがって、ここではオプションの末尾を削除して、pngファイルで構成された各一意の文字列のディレクトリを作成します.png

bashGNUツールを使用すると、次のことができます。

#! /bin/bash -
export LC_ALL=C # needed for sed to deal with arbitrary byte values, for
                # [0-9] to match on 0123456789 only and for sort -u to report
                # unique records as opposed to one of several that sort the
                # same.

shopt -s failglob # to properly handle the cases where there's no png
set -o pipefail   # ditto, to report a failure exit status in that case.

printf '%s\0' *.png |
  sed -Ez 's/( [0-9]+)?\.png$//' |
  sort -zu |
  xargs -r0 mkdir -p --

またはGNUismを避け、bash 4+を使用してください。

#! /bin/bash -
shopt -s failglob extglob
typeset -A unique
files=(*.png) || exit
for file in "${files[@]}"; do
  file=${file%.png}
  file=${file% +([0123456789])}
  unique[$file]=
done
mkdir -p -- "${!unique[@]}"

現在のディレクトリに名前がファイルの場合、" 12.png"ディレクトリ名は空になります。上記の最後のbash解決策では、連想配列が空のキーを持つ要素をサポートしていないため、構文エラーが発生し、他のすべての解決策では名前が空の要素を生成しないbashエラーが発生します。mkdir

macOSはデフォルトではGNUツールには付属しておらず、非常に古いバージョンに同梱されていますbashzshしかし、常に存在していました。必ず使用する必要がbashあり、最新バージョンまたはGNUツールをインストールできない場合は、次のものを代わりに使用できますperl

#! /bin/bash -
perl -e '
  for (<*.png>) {
    s/\.png\z//;
    s/ \d+\z//;
    $unique{$_} = undef;
  }
  $ret = 0;
  for (keys %unique) {
    unless (mkdir($_) || ($!{EEXIST} && -d $_)) {
      warn "Cannot create $_: $!\n";
      $ret = 1;
    }
  }
  exit $ret;'

bashこのコードの具体的な内容は、インストールされている限り、shどのシステムでも機能しませんperl。)

関連情報