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.* .
불행하게도 pax
POSIX 및 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.*'