前に追加した親ディレクトリ名を使用してファイル名を変更する

前に追加した親ディレクトリ名を使用してファイル名を変更する

コマンドを使用せずに、親ディレクトリ名の前に追加されたファイルの名前を一括変更する必要がありますrename

例えば

/tmp/2017-09-22/cyber.gz
/tmp/2017-09-23/cyber.gz
/tmp/2017-09-24/cyber.tar

/tmp/archive名前が変更されたファイルも、上記のソースファイルに影響を与えずにコピーする必要があります。

以下のように

/tmp/archive/2017-09-22_cyber.gz
/tmp/archive/2017-09-23_cyber.gz
/tmp/archive/2017-09-24_cyber.tar

答え1

ここで使用しない場合は、rename次のことができます。Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion

find * -path "archive" -prune -o -type f -exec \
    bash -c 'echo "$1" "archive/${1/\//_}"' find_bash '{}' \;
  • -path "archive" -prunearchiveディレクトリ自体は含まれません。

  • ${1/\//_}/スラッシュを下線に置き換えます_。渡されたファイルパスである1最初のパラメータを指します。find_bash{}

(ファイルのコピーまたは移動echoに置き換えます)cpmv

ディレクトリ構造:

.
├── 2017-09-22
│   └── cyber.gz
├── 2017-09-23
│   └── cyber.gz
├── 2017-09-24
│   └── cyber.tar
└── archive

コマンドを実行した後:

.
├── 2017-09-22
│   └── cyber.gz
├── 2017-09-23
│   └── cyber.gz
├── 2017-09-24
│   └── cyber.tar
└── archive
    ├── 2017-09-22_cyber.gz
    ├── 2017-09-23_cyber.gz
    └── 2017-09-24_cyber.tar

答え2

短いシェルスクリプトを使用してください。

#!/bin/sh

archive='/tmp/archive'

mkdir -p "$archive"

for name in /tmp/????-??-??/*; do
    dirdate=${name%/*}         # dirdate=$(dirname "$name")
    dirdate=${dirdate##*/}     # dirdate=$(basename "$dirdate")

    newname="$archive/${dirdate}_${name##*/}"

    if [ ! -e "$newname" ]; then
        echo cp "$name" "$newname"
    fi
done

dirdateこれは、日付と呼ばれるディレクトリのデフォルト名を選択し、それを使用して内部の各ファイルの新しい名前を作成します。

新しい名前がディレクトリにない場合、ファイルはarchiveそのディレクトリにコピーされます。

echo実際にコピーを実行するために上記のスクリプトから削除されました。

与えられた例では、スクリプトは次のことを行います。

cp /tmp/2017-09-22/cyber.gz /tmp/archive/2017-09-22_cyber.gz
cp /tmp/2017-09-23/cyber.gz /tmp/archive/2017-09-23_cyber.gz
cp /tmp/2017-09-24/cyber.tar /tmp/archive/2017-09-24_cyber.tar

関連情報