我目录中有一些名为IMG_0001.jpg
...的文件IMG_9999.jpg
。我想将按字典顺序排列的名称大于的文件移动到另一个目录中,IMG_9431.jpg
我该怎么做?
答案1
您可以使用sort
和sed
来获取大于某些字符串的文件列表,如下所示:
$ ls -v
0?#Li 23?24 E.See NULib Yoush ce-Su edint ethat ibble itwil lines of16 plesA ryGen t6?#C witht #ver
0?#mo 25?i Examp NYWAR along cribb edist ev ibrar ix B. mapfo ofthe ppend sdist tetot y8?#9 (atyo
0,22 27?# FORAP NextA areFo dacop edwar frees ic11 lPubl mored oftwa publi sefor theGN yGene )1995
1.scr 02111 Finla Peter aryis datio eful, ftheG ight( landJ mport on23# ralPu se,or tunde yofth ,USA.
1-200 ARTIC GIMPT RANTY avere difyi eitan ftwar imbal lbeus ncerK on,MA raryG shedb t,wri ytheF ;ifno
2John Appen HANTA Softw bleof dix B enera ght(C impli ld7?# nc.,5 oolki raryi simpl ublic #19?# ;with
4?#Th BILIT HOUTA TNESS blic2 e.py4 enthe gtk26 ingar lePla ngpix opyri rdraw sion. ucanr #Bost Code
5?#GT Backi K-The U17?# brary e.pyB eralP he21 ion)a lesPr nseas oshMa reeSo sion2 undat #Free
9Temp Conte Libra ULARP cDona eExam ermso hehop ion,I lesTa ntsB. ouldh re;yo slibr uropt #Lice
13?#1 Copyr Licen URPOS ceive eFoun erver her12 islib lescr nylat outev ribut s,Spe utWIT #MERC
15?#b C)200 Matti YorFI cense eGNUL etail hisli ite33 lesim n;eit ple.p rthet s.18 vpyth #Thi
$ mkdir greater-than-sion
魔术就在这里:
$ find -type f -print0 |
sort -z |
sed -z '1,/sion/d' |
xargs -0 mv -t greater-than-sion
行:
- 打印文件列表,使用( )
NUL
而不是换行符分隔-print0
- 对它们进行排序
- 删除行低于(包括)一些字符串(此处
sion
)——请注意,这只适用于 GNUsed
,它实现了-z
解析NUL
-terminated 输入的选项 - 将此列表传递
mv
给xargs
期望的结果:
$ ls -R
.:
Code ;ifno 25?i avere Conte edist erver GIMPT ic11 K-The lines nseas opyri raryG se,or
#19?# ;with 27?# Backi Copyr edwar etail greater-than-sion/ ight( landJ lPubl ntsB. oshMa raryi sefor
#Bost 0?#Li 2John BILIT cribb eExam ethat gtk26 imbal lbeus mapfo NULib ouldh rdraw shedb
#Free 0?#mo 4?#Th bleof dacop eFoun ev HANTA impli ld7?# Matti nylat outev re;yo simpl
#Lice 0,22 5?#GT blic2 datio eful, Examp he21 ingar lePla mored NYWAR Peter reeSo sion.
#MERC 02111 9Temp brary difyi eGNUL Finla hehop ion)a lescr mport of16 ple.p ribut
#Thi 1.scr along C)200 dix B eitan FORAP her12 ion,I lesim n;eit ofthe plesA rthet
#ver 1-200 Appen cDona e.py4 enera frees hisli islib lesPr nc.,5 oftwa ppend ryGen
(atyo 13?#1 areFo ceive e.pyB enthe ftheG HOUTA ite33 lesTa ncerK on,MA publi s,Spe
)1995 15?#b ARTIC cense E.See eralP ftwar ibble itwil Libra NextA on23# ralPu s.18
,USA. 23?24 aryis ce-Su edint ermso ght(C ibrar ix B. Licen ngpix oolki RANTY sdist
./greater-than-sion:
sion2 Softw t6?#C theGN tunde ublic ULARP uropt utWIT witht yGene YorFI ytheF
slibr t,wri tetot TNESS U17?# ucanr undat URPOS vpyth y8?#9 yofth Yoush
答案2
和括号扩展,适用于 Bash 3 及更高版本以及 Zsh 和其他几个 shell:*
mv IMG_{9431..9999}.jpg some_other_dir
括号将扩展为 9431 至 9999 之间的所有数字,因此相当于写出以下内容:
mv IMG_9431.jpg IMG_9432.jpg … IMG_9999.jpg some_other_dir
如果文件太多,此操作将会失败(请参阅这篇文章关于ARG_MAX
了解背景信息。
如果你的 shell 缺少括号扩展功能,或者你有太多文件,你可以这样做 - 但可能会慢一点:
for n in $(seq 9431 9999); do mv "IMG_$n.jpg" some_other_dir; done
如果你真的想按字典顺序排序,看看Ярослав Рахматуллин 的回答。比下面的内容好多了。
您必须以某种方式对文件名进行排序。这是我很快想到的办法,但并不美观,也远非理想。它适用于 GNU/Linux(grep
、sort
、xargs
),并处理任何文件名,包括引号和空格。
tmp="$(mktemp /tmp/files.XXX)"
find . -type f -name 'IMG*' -maxdepth 1 -print0 | sort -z > "$tmp"
line=$(grep -nz IMG_9984.jpg "$tmp" | cut -d: -f1)
tr '\0\n' '\n\0' < "$tmp" | tail -n "+$line" | tr '\0\n' '\n\0' |
xargs -0 -I{} echo mv {} some_other_dir
rm "$tmp"
echo
当您确定这能满足您的要求时,请删除。我们在这里所做的是:
创建一个临时文件来保存文件名。
查找与模式匹配的所有文件,并将它们排序到临时文件中。记录由
NUL
字符 (-print0
,-z
) 分隔,因此我们可以处理任何文件名。查找文件名的“行”号,例如
IMG_9984.jpg
NUL
临时文件中的交换和换行所以tail
可以处理它。将它们交换回来以便
xargs
可以处理它(-0
)并将mv
文件放到其他目录中。
如果我们不必处理包含引号或空格的文件,这会更容易,但是……这只是我的看法。谨慎一点总比后悔好。