根據名稱查找文件並同時重命名移動它們
考慮我有根據年份命名的目錄並包含根據主題程式碼的 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
與./xyz/Nov-Dec-2011.pdf
、./Summer-2012/161901.pdf
to等類似./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
或使用循環或其他東西)
Perl 模組Unicode::Tussle帶有一個非常有用的名為rename
rename(1)
的腳本(很不幸,因為該名稱與Linux上的標準衝突)。有了它,你可以做這樣的事情:mkdir xyz find . -name '*.pdf' -print0 | \ rename -0 's!^\.!xyz!; s!/[^/]*\.pdf$!.pdf!'
如果沒有 Perl,你仍然可以通過一些 shell 管道來做同樣的事情:
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
而且,我相信其他人會很快指出,您甚至可以使用
<(...)
流程替換將其放在一行上。我不確定這會讓事情變得更清晰。如今的電腦已經足夠強大,可以使用更冗長的語法。;)
find
當您不需要遞歸遍歷目錄樹時,它很少有用。這裡一個簡單的循環和 shell 萬用字元就足夠了。for x in */161901.pdf; do mv -- "$x" "xyz/${x%/*}.pdf" done
rename
或者,在 Debian、Ubuntu 和衍生產品上使用基於 Perl 的命令(prename
在 Arch 上,而不是rename
其他發行版上的 Linux 命令):rename 's!/.*!!; $_="xyz/$_.pdf"' */161901.pdf
或者,使用 zsh:
autoload -U zmv zmv '(*)/161901.pdf' 'xyz/$1.pdf'