用于模式匹配和删除文件的bash脚本
问题:在目录中,我有以下格式的文件:用于模式匹配和删除文件的bash脚本,bash,shell,Bash,Shell,问题:在目录中,我有以下格式的文件: <account-number>-<invoice-number>, an example being: 123456-3456789 123456-6789023 123456-2568907 ... 456789-2347890 456789-2344357 etc. 我想做的是,如果同一个帐户有多个发票,请删除除最新发票之外的所有发票。如果只有一个,别管它 感谢您的指点。您可以使用此基于awk的脚本: mkdir _tmp
<account-number>-<invoice-number>, an example being:
123456-3456789
123456-6789023
123456-2568907
...
456789-2347890
456789-2344357
etc.
我想做的是,如果同一个帐户有多个发票,请删除除最新发票之外的所有发票。如果只有一个,别管它
感谢您的指点。您可以使用此基于awk的脚本:
mkdir _tmp
ls -rt *-*|awk -F'-' '{a[$1]=$0} END{for (i in a) system("mv " a[i] " _tmp/")}'
一旦您对中的文件感到满意。/\u tmp/从当前目录中删除所有文件并将文件移到另一个目录。这里有一个纯bash解决方案,在验证echo时将其替换为rm
for file1 in *-*
do
IFS=- arr=($file1)
for file2 in "${arr[0]}"*
do
[ "$file1" -nt "$file2" ] && echo "$file2"
done
done
Bash中的一个不错的例子:
伪就地处理
#!/bin/bash -e
ADIR="/path/to/account/directory"
TMP="$ADIR.tmp"
mkdir "$TMP" && rmdir "$TMP" && mv "$ADIR" "$TMP" && mkdir "$ADIR"
while IFS=- read ACCNT INVOICE < <( ls -t1 "$TMP" )
do
mv "$TMP/$ACCNT-$INVOICE" "$ADIR/$ACCNT-$INVOICE" && rm "$TMP/$ACCNT"*
done
rmdir "$ADIR.tmp"
它的作用是:
1首先将帐户目录移动到临时目录。是原子的
2在循环中:列出最新发票,将其移动到新目录,删除具有相同帐户的发票。
3删除临时目录
优点:
可靠、安全、简短、速度合理,并在出现严重错误时停止
缺点:
非常明确,确保始终有备份
评论:
您可能已经注意到mkdir$TMP&&rmdir$TMP
这是故意的:rmdir为dir not exist提供与dir not empty相同的返回值
因此,与其检查两者中的哪一个
[-d$DIRNAME]&&&{rmdir$DIRNAME | | exit}
我使用了上面的结构
此外,ls-t1$TMP可能是在一个陌生的地方乍一看
但是没关系,每次迭代都会再次执行,但只读取第一行您如何判断帐号是什么?在-?是之前,对于123456-3456789,123456是账号,3456789是发票号。所以在上面的例子中,如果123456-3456789是最新的,我想删除以123456等开头的另外两个。最新的发票是由时间戳或发票号决定的?Anubhava的解决方案对您不起作用还是您想要更优雅的阅读一行?不起作用。所有最新的文件都没有移到tmp。对不起,我没有看到时间戳检查?太棒了!非常感谢。