cp는 패턴을 상위 디렉토리와 일치시킵니다.

cp는 패턴을 상위 디렉토리와 일치시킵니다.

패턴과 일치하는 상위 디렉터리로 디렉터리 복사

cp 
dir/group1/sub01/./././DCM
dir/group2/sub01/././DCM
to 
dir/Base/group1/sub01/Time1/
dir/Base/group2/sub01/Time1/
with matched group name and sub name
output: 
dir/Base/group1/sub01/Time1/DCM
dir/Base/group2/sub01/Time1/DCM

아마 생각하고 있어요

find * -type d -name "DCM" -execdir bash -c 'old="$1"; new="$(cd ../../..; basename --"$PWD")/$(cd ../..; basename --"$PWD")"; cp -r "$old" "dir/Base/$new"' - {} \;

어떤 제안이 있으십니까?

답변1

길고 복잡한 줄을 작성하는 대신 다음을 수행하는 것이 좋습니다 awk.

new_dir=$(echo "$dir" | awk -F\/ '{print "dir/Base/"$2"/"$3"/Time1/"}')

스크립트는 다음과 같습니다.

while read dir
do
  new_dir=$(echo "$dir" | awk -F\/ '{print "dir/Base/"$2"/"$3"/Time1/"}')
  cp -fdR "$dir" "$new_dir"
done <(find . -type d -name DCM)

답변2

사용 zsh:

autoload -U zmv
zmv -v -C -o -R -- 'dir/(group<->)/(sub<->)/**/DCM' 'dir/Base/$1/$2/Time1/'

위 명령은 zmv확장된 와일드카드 패턴과 대상 경로 이름을 사용합니다. 와일드카드 패턴에는 등을 사용하여 대상 경로 이름에서 $1참조 할 수 있는 "캡처 그룹"(괄호 안의 표현식)이 포함될 수 있습니다. 위 명령은 $2하위 디렉터리의 이름(모든 숫자가 일치하는 곳)을 캡처합니다.groupsub<->

여기에 사용된 옵션은 -n"시험 실행"(실제 복사를 수행하지 않음, 작동한다고 확신하면 제거), -v"자세한" 작업 및 -C이동 대신 복사를 위한 것입니다. 우리는 에 -o -R전달하는 데 사용합니다 .-Rcp

시험:

$ tree
.
`-- dir
    |-- Base
    |   |-- group1
    |   |   `-- sub01
    |   |       `-- Time1
    |   `-- group2
    |       `-- sub01
    |           `-- Time1
    |-- group1
    |   `-- sub01
    |       `-- a
    |           `-- b
    |               `-- c
    |                   `-- DCM
    `-- group2
        `-- sub01
            `-- a
                `-- b
                    `-- DCM
$ zmv -v -C -o -R -- 'dir/(group<->)/(sub<->)/**/DCM' 'dir/Base/$1/$2/Time1/'
cp -R -- dir/group1/sub01/a/b/c/DCM dir/Base/group1/sub01/Time1/
cp -R -- dir/group2/sub01/a/b/DCM dir/Base/group2/sub01/Time1/
$ tree
.
`-- dir
    |-- Base
    |   |-- group1
    |   |   `-- sub01
    |   |       `-- Time1
    |   |           `-- DCM
    |   `-- group2
    |       `-- sub01
    |           `-- Time1
    |               `-- DCM
    |-- group1
    |   `-- sub01
    |       `-- a
    |           `-- b
    |               `-- c
    |                   `-- DCM
    `-- group2
        `-- sub01
            `-- a
                `-- b
                    `-- DCM

답변3

다음과 같이 작동할 수 있습니다.

#!/bin/bash

set -e -o pipefail


find . -type d -name DCM | while read dir; do
  new_dir_suffix=`echo "$dir" | sed 's/^.*group/group/' | sed 's|\(sub[0-9]*\).*DCM|\1/Time1|'`
  cp -fdR "$dir" dir/base/"$new_dir_suffix"
done

명령에서 변수를 설정하면 bash -c이러한 변수는 Bash 호출의 컨텍스트 내에서만 존재하므로 아무런 효과가 없습니다. 을(를) 팔로우할 수 없습니다 find.

관련 정보