연도를 기준으로 이름이 지정된 디렉토리가 있고 테마 코드를 기반으로 하는 PDF 파일이 포함되어 있다고 가정해 보겠습니다.
ls
출력은 다음과 같습니다
$ ls -l
total 32
drwxrwxrwx 1 root root 4096 Apr 8 08:52 May-June-2011
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Nov-Dec-2011
drwxrwxrwx 1 root root 4096 Apr 8 20:36 Summer-2012
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Summer-2013
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Summer-2014
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Winter-2012
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Winter-2013
drwxrwxrwx 1 root root 4096 Apr 8 08:52 Winter-2014
각 디렉토리에는 제목 코드에 따른 pdf 파일이 포함되어 있습니다.
ls -l May-June-2011/
total 808
-rwxrwxrwx 1 root root 104193 May 1 2011 161901.pdf
-rwxrwxrwx 1 root root 103380 May 1 2011 161902.pdf
-rwxrwxrwx 1 root root 115664 May 1 2011 161903.pdf
-rwxrwxrwx 1 root root 88953 May 1 2011 161904.pdf
-rwxrwxrwx 1 root root 179268 May 1 2011 161905.pdf
-rwxrwxrwx 1 root root 116158 May 24 2011 161906.pdf
-rwxrwxrwx 1 root root 106033 May 1 2011 161907.pdf
즉, 모든 디렉토리에는16190{1..7}.pdf
161901.pdf
이제 언급된 모든 디렉터리의 모든 항목을 특정 디렉터리(예: xyz
)로 이동하고 이름을 상위 폴더의 name.pdf로 바꾸려고 한다고 가정합니다 .
설명하다:-
다음은 그 목록입니다 161901.pdf
.
$ find -name 161901.pdf
./May-June-2011/161901.pdf
./Nov-Dec-2011/161901.pdf
./Summer-2012/161901.pdf
./Summer-2013/161901.pdf
./Summer-2014/161901.pdf
./Winter-2012/161901.pdf
./Winter-2013/161901.pdf
./Winter-2014/161901.pdf
./May-June-2011/161901.pdf
새로운 이름(파일이 위치한 디렉토리 이름)으로 옮겨 졌으면 좋겠습니다 . 즉, 다음으로 이동xyz
May-June-2011.pdf
./May-June-2011/161901.pdf
./xyz/May-June-2011.pdf
마찬가지로 , ./Nov-Dec-2011/161901.pdf
to 등 ( to 까지 )../xyz/Nov-Dec-2011.pdf
./Summer-2012/161901.pdf
./xyz/Summer-2012.pdf
./Winter-2014/161901.pdf
./xyz/Winter-2014.pdf
예상되는 출력 ls xyz
은 다음과 같습니다.
$ls xyz
May-June-2011.pdf
Nov-Dec-2011.pdf
Summer-2012.pdf
Summer-2013.pdf
Summer-2014.pdf
Winter-2012.pdf
Winter-2013.pdf
Winter-2014.pdf
어떻게 해야 하나요? (루프 또는 기타 방법 find -exec
또는 사용 방법)
답변1
펄 모듈유니코드::싸움다음과 같은 매우 유용한 스크립트가 함께 제공됩니다.이름을 바꿔라(이 이름은 Linux의 표준과 충돌하므로 이는 불행한 일입니다 rename(1)
.) 그것으로 당신은 다음과 같은 일을 할 수 있습니다 :
mkdir xyz
find . -name '*.pdf' -print0 | \
rename -0 's!^\.!xyz!; s!/[^/]*\.pdf$!.pdf!'
Perl이 없어도 일부 쉘 파이핑을 사용하여 동일한 작업을 수행할 수 있습니다.
mkdir xyz
find . -name '*.pdf' | sed 's/^/mv /' >src
find . -name '*.pdf' | sed 's!^\./!xyz/!; s!/[^/]*\.pdf$!.pdf!' >dest
join src dest | sh -
rm -f src dest
그리고 다른 사람들이 금방 지적할 것이라고 확신하지만 <(...)
프로세스 대체를 사용하여 한 줄에 넣을 수도 있습니다. 그러나 이것이 상황을 더 명확하게 만드는지는 확실하지 않습니다. 오늘날의 컴퓨터는 더 자세한 구문을 사용할 수 있을 만큼 강력합니다. ;)
답변2
find
디렉터리 트리를 재귀적으로 탐색할 필요가 없을 때는 거의 유용하지 않습니다. 여기서는 간단한 루프와 쉘 와일드카드로 충분합니다.
for x in */161901.pdf; do
mv -- "$x" "xyz/${x%/*}.pdf"
done
rename
prename
또는 Debian, Ubuntu 및 그 파생 제품( 다른 배포판의 Linux 명령이 아닌 Arch의 경우 rename
) 에서 Perl 기반 명령을 사용합니다 .
rename 's!/.*!!; $_="xyz/$_.pdf"' */161901.pdf
또는 zsh를 사용하세요.
autoload -U zmv
zmv '(*)/161901.pdf' 'xyz/$1.pdf'
답변3
find -print
한 가지 방법은 파일 목록을 가져와서 다음 명령 awk
과 같이 원하는 대로 변환할 수 있는 위치 로 파이프하는 것입니다.cp
$ find -name 161901.pdf -print | awk -v TARGET=xyz -F'/' '{ printf "cp %s %s/%s.pdf\n", $0, TARGET, $2; }'
cp ./May-June-2011/161901.pdf xyz/May-June-2011.pdf
cp ./Nov-Dec-2011/161901.pdf xyz/Nov-Dec-2011.pdf
그런 다음 실행을 위해 셸로 파이프될 수 있습니다.
find -name 161901.pdf -print | awk -v TARGET=xyz -F'/' '{ printf "cp %s %s/%s.pdf\n", $0, TARGET, $2; }' | sh
답변4
당신이 가지고 있다면이름 바꾸기/이름 바꾸기주문하다
find -name 161901.pdf -exec prename -n 's!/!-!g; s!\W*!xyz/!' {} +
-n
보시고 마음에 드시면 삭제해주세요.
(Larry Wall과 Robin Barker의 이름은 perl.deb 패키지와 함께 설치되며 Brian d Foy의 Unicode::Tussle
이름 변경도 가능합니다.)