ファイル名の一部に基づいてターゲットディレクトリからファイルを見つけてコピーします。

ファイル名の一部に基づいてターゲットディレクトリからファイルを見つけてコピーします。

Linux shスクリプトを探しています。

  1. フォルダを解析して特定の拡張子を見つけます。
  2. ファイル名の一部に基づいて、これらすべてのファイルをフォルダにコピーします。

これまでに2つのコマンドラインを正常に作成しました。

ファイル名の一部に基づいてフォルダを作成する方法の唯一の欠点は、現在のフォルダの代わりに「Out」フォルダにこれらのフォルダをすべて作成することを好むことです。

find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) \
 | tr -s '[:blank:]' '_' \
 | cut -d"-" -f1 \
 | xargs mkdir -p

2番目は、静的フォルダOutにあるすべてのファイルをコピーします。

find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) -exec cp '{}' Out \

2つのコマンドを組み合わせて、名前に基づいてサブフォルダにファイルをコピーすることはできません(サブフォルダがない場合はサブフォルダを作成します)。

助けてくれてありがとう!

答え1

prenameここでは、専用ファイルの名前変更ツール(例:mmvまたは. がPOSIXとユーティリティを使用する必要がある場合は、次のようにします。zshzmvsh

find . ! -name . -prune \( -name '*.xxx' -o -name '*.yyy' \) -type f -exec sh -c '
  ret=0
  for file do
    name=${file##*/}
    dstdir=Out/$(printf "%s\n" "${name%%-*}" | tr -s "[:space:]" "[_*]")
    mkdir -p "$dstdir" &&
      cp "$file" "$dstdir/" &&
      true > "$file" || ret=$?
  done
  exit "$ret"' sh {} +

(また、いくつかのGNUismを避けます)。

答え2

私はそれを2つの部分に分けてやります:

まず、先ほどのようにディレクトリを作成します。

find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) \
| tr -s '[:blank:]' '_' \
| cut -d"-" -f1 \
| xargs mkdir -p

2番目はbash中括弧拡張を利用しています...

find . -maxdepth 1 -type d -not -name '.' -exec bash -c 'cp ${1}*.{xxx,yyy} ${1}/' _ {} \;

結果:

$ tree
.
├── 519_RU
│   ├── 519_RU-1801013_20181217_141826_656.xxx
│   └── 519_RU-1801013_20181217_143011_657.xxx
├── 519_RU-1801013_20181217_141826_656.xxx
├── 519_RU-1801013_20181217_143011_657.xxx
├── 825_RU
│   └── 825_RU-1809008_20190723_015635_947.yyy
├── 825_RU-1809008_20190723_015635_947.yyy
└── AB47

in xxx yyy拡張リストを生成するコマンドを置き換えることができます。

答え3

助けてくれてありがとう。ついに私に多くの役に立った別のトピックに基づいて解決策を見つけました。ここ

以下をご覧ください。

find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) -size +0 -exec env file={} bash -c 'base="$(basename "$file" | tr -s '[:blank:]' '_' |cut -d"-" -f1)" ;dir="Out/${base%.*}";mkdir -p "$dir";cp "$file" "$dir" ; truncate "$file" -s 0 ' \;

関連情報