와일드 카드로 여러 파일을 복사하려면 어떻게합니까? 파일이있는 폴더가

ABC. *에 많은 파일이있는 폴더가 있습니다 (대략 100 개의 파일이 있습니다). 이름을 DEF로 시작하는 새 파일에 모두 복제하고 싶습니다. *

그래서 나는 원한다

ABC.Page1
ABC.Page2
ABC.Topic12
...etc

에 복사

DEF.Page1
DEF.Page2
DEF.Topic12
...etc

배치 명령으로 BASH 또는 이와 유사한 방법을 사용하는 가장 간단한 방법은 무엇입니까? sed 또는 awk 또는 xargs와 관련된 것을 생각하고 있지만 구문을 파악하는 데 어려움이 있습니다. 파이썬 스크립트를 작성할 수는 있지만 너무 복잡하지 않은 명령 줄 솔루션이 있다고 생각합니다.



답변

bash에서 이와 같은 것은 어떻습니까?

for file in ABC.*; do cp "$file" "${file/ABC/DEF}";done

cp 명령 앞에 echo를 넣어서 테스트 할 수 있습니다.

for file in ABC.*; do echo cp "$file" "${file/ABC/DEF}";done

답변

많은 수의 파일로이 작업을 효율적으로 수행하려면 각 파일 cp마다 다른 프로세스를 시작하지 않는 것이 좋습니다 . 한 가지 방법은 다음을 사용하여 파일을 복사 한 다음 이름을 바꾸는 것입니다 prename( rename데비안 기반 배포판에서는 기본적으로 심볼릭 링크 됨). 이것과 리눅스 사용하기 mktemp:

tmp=$(mktemp -d --tmpdir=.)
cp ABC.* "$tmp"
prename "s:$tmp/ABC:DEF:" "$tmp/"*
rmdir "$tmp"

최신 정보

실제로 pax여기에 더 나은 방법 일 수 있습니다.

pax -rws '/^ABC/DEF/' ABC.* .

불행히도 paxPOSIX와 Linux Standard Base 모두 에 불구하고 현재 기본적으로 포함되는 배포판은 거의 없습니다.


답변

tar 정말 빨리 당신을 위해 이것을 할 것입니다.

테스트

먼저 2 개의 디렉토리와 10 개의 파일을 만들었습니다.

% mkdir test1 test2 ; cd test1
% for n in `seq 1 10` ; do touch ABC.file$n ; done
% ls

> ABC.file1   ABC.file2  ABC.file4  ABC.file6  ABC.file8
> ABC.file10  ABC.file3  ABC.file5  ABC.file7  ABC.file9

그런 다음 복사했습니다.

% tar -cf - ./* |\
    tar -C../test2 --transform='s/ABC/DEF/' -xf -
% ls ../test2

> DEF.file1   DEF.file2  DEF.file4  DEF.file6  DEF.file8
> DEF.file10  DEF.file3  DEF.file5  DEF.file7  DEF.file9

변환

따라서 GNU tarsed --transform=EXPRESSION파일 이름 바꾸기를 허용합니다 . 파일의 일부만 이름을 바꿀 수도 있습니다. 예를 들어 :

% tar -cf - ./* |\
    tar -C../test2 --transform='s/ABC\(.*[0-5]\)/DEF\1/' -xf -
% ls ../test2

> ABC.file6  ABC.file8  DEF.file1   DEF.file2  DEF.file4
> ABC.file7  ABC.file9  DEF.file10  DEF.file3  DEF.file5

이것이 한 가지 장점입니다.

흐름

또한이 tar프로세스 는 두 개의 프로세스에 불과 하며 파일 수에 관계없이 변경되지 않습니다.

tar | tar

tar당신이 원하는만큼 최적화되어 있습니다. 이것은 문제 인수 수 또는 폭주 하위 프로세스를 갖지 않습니다. 이것은 단지 A> B 입니다.

인수

나는 두 tar프로세스 사이에 7 개의 구별 된 인수를 사용한다 . 가장 중요한 것이 먼저 여기에 나열됩니다.

-표준 출력 / 표준 입력 -이 정보 용 tar그것으로 하나의 입력 또는 출력을 스트리밍한다으로부터 또는 stdin/stdout어느 올바르게은 건물 또는 아카이브 추출되어 있는지의 여부에 따라 해석된다.

-c생성 -이 이야기 tar아카이브를 구축 할 수 있습니다. 다음 주장 tar은 …

-f파일 – 테이프 장치 등이 아닌 객체 tar로 작업하도록 지정합니다 file. 그리고 위에서 언급했듯이 작업 할 파일은 stdin/stdout다시 말해 우리의 파일 |pipe입니다.

./*모든 $ PWD / 파일 – 너무 많은 아카이브 인수가 있으므로, 먼저 것을 제외하고 여기에 설명하지 -다음 ./*.

… 그리고 반대편에 |pipe

-C디렉토리 변경tar다른 조치를 수행하기 전에 내가 지정한 디렉토리로 변경해야하므로 효과적으로 cd ../test2추출하기 직전에 변경 해야합니다.

--transform='s/ed/EXPR/'-이미 언급했듯이 이름을 바꿨습니다. 그러나 문서는 모든 sed표현을 취할 수 있음을 나타냅니다 //flag.

-xextract-tar 대상 디렉토리로 변경 한 후 이름 바꾸기 지시 사항을 수신하면 -f - |pipe아카이브 파일 에서 현재 디렉토리로 모든 파일의 추출을 시작하도록 지시 합니다. 미스터리가 없습니다.


답변

덜 표준적인 도구를 사용하는 것이 마음에 들지 않으면 이런 종류의 작업을 위해 작성된 mmv (질량 이동)를 사용하는 것이 좋습니다 . mcp제품군의 일부인 (대량 복사)를 사용하면 간단히 할 수 있습니다.

mcp "ABC.*" "DEF.#1"

다운로드 패키지를 찾는 것은 쉽지 않습니다. 집에서 컴파일하기 위해 현재 데비안 패키지 (Arch에서도 AUR에서 사용)는 여기 에서 찾을 수 있습니다 .


답변

zsh에서 다음 행을 다음에 넣으십시오 .zshrc.

autoload -U zmv
alias zmv='noglob zmv'
alias zcp='zmv -C'
alias zln='zmv -L'

그런 다음 명령 행에서 다음을 실행할 수 있습니다.

zcp 'ABC(.*)' 'DEF$1'

또는 단순히

zcp -W ABC.* DEF.*

zsh가 설치되어있는 한 다른 쉘에서 :

zsh -c 'autoload zmv; noglob zmv -CW ABC.* DEF.*'

답변

당신은 이것을 할 수 있습니다 :

for i in ABC.*; do cp {ABC,DEF}."${i#*.}"; done