와일드카드를 통해 여러 파일을 복사하는 방법은 무엇입니까?

와일드카드를 통해 여러 파일을 복사하는 방법은 무엇입니까?

ABC.*라는 많은 파일이 포함된 폴더가 있습니다(이러한 파일이 약 100개 있습니다). DEF로 시작하는 이름을 가진 새 파일에 모두 복사하고 싶습니다. *

그래서 나는 원한다

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

에게 복사

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

BASH 또는 이와 유사한 배치 명령을 사용하여 이 작업을 수행하는 가장 쉬운 방법은 무엇입니까? sed, awk 또는 xargs와 관련된 문제를 생각하고 있지만 구문을 파악하는 데 문제가 있습니다. Python 스크립트를 작성할 수도 있지만 덜 복잡한 명령줄 솔루션이 있을 수도 있다고 생각했습니다.

답변1

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

답변2

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

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

고쳐 쓰다

실제로 pax더 나은 접근 방식이 될 수 있습니다.

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

불행하게도 paxPOSIX 및 Linux 표준 라이브러리이지만 현재 기본적으로 이를 포함하는 배포판은 거의 없습니다.

답변3

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는 파일 이름 바꾸기를 tar허용합니다 . sed --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/파일- 여기서는 archive 매개변수가 먼저 온다는 점을 제외하면 별다른 설명이 -없습니다 ./*.

|pipe...그리고 반대편에는

-C디렉토리 변경- 이는 tar다른 작업을 수행하기 전에 내가 지정한 디렉터리로 변경해야 한다는 의미이므로 cd ../test2압축을 풀기 전에 작동합니다.

--transform='s/ed/EXPR/'- 이미 언급했듯이 이것으로 이름 바꾸기가 완료됩니다. 그러나 문서에는 어떤 표현식 sed이나 //flag.

-x정제- tar대상 디렉터리를 변경하고 이름 변경 명령을 받은 후 아카이브의 모든 파일을 현재 디렉터리로 추출하기 시작하도록 지시합니다 -f - |pipe. 그것에 대해 신비한 것은 없습니다.

답변4

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.*'

관련 정보