在Linux中使用Bash来获取文件名并删除类似命名的文件

时间:2014-06-03 00:46:53

标签: linux bash

我试图查看目录并根据文件名删除重复文件。我使用以下代码执行此操作:

    for i in `seq 1 10`;
    do
        rm "$d"/*\($i\).mp3
    done

这会保留song.mp3并删除歌曲(1).mp3,song(2).mp3等等,最多可重复10次。

然而,我意识到原始文件不是没有复制(1).mp3或(2).mp3的文件,而是重复编号最高的文件(最早的修改日期),在这种情况下会是歌(2).mp3。这是因为出于某种原因我正在使用的程序将原始文件重命名为song(1).mp3并命名最新的文件song.mp3。

所以我想在上面的例子中做的是将song.mp3和song(1).mp3和mv song(2).mp3删除到song.mp3,这样它的修改日期就不会改变。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

此解决方案适用于所有文件,而不仅适用于手动指定的内容,如d="song" 。我希望代码注释是自我解释的:

# Iterate through all file name prefixes of candiates
while read prefix ; do

    [[ -z "$prefix" ]] && continue

    # Get the oldest file. (The one with the largest suffix value for this prefix)
    oldest=$(find -maxdepth 1 -type f -name "$prefix(*).mp3" | sort -t\( -k2r | head -n1)

    # Overwrite the newest with the oldest file.
    mv -v "$oldest" "$prefix.mp3"

    # Delete the files between oldest and newest
    rm -fv "$prefix(*.mp3"

done <<< $(find -maxdepth 1 -type f -regex '.*([0-9]+).mp3' -printf "%f"  |  cut -f 1 -d\(  | uniq)

答案 1 :(得分:1)

i="1"

# If song(1).mp3 doesn't exist, there's nothing to do.
if [[ -f "$d/($i)".mp3 ]]
then
   # Remove song.mp3
   rm "$d".mp3

   # If song(n+1).mp3 exists, delete song(n).mp3 
   j=$((i+1))
   while [[ -f "$d/($j)".mp3 ]]
   do
      rm "$d/($i)".mp3
      i=$j
      j=$((i+1))
   done

   # Move song(n).mp3 to song.mp3
   mv "$d/($i)".mp3 "$d".mp3
fi

答案 2 :(得分:0)

您可以使用globbing并将每个副本移动到原始文件上:

FILE=./song
EXT=mp3
for f in $FILE*.$EXT
do
    mv $f $FILE.$EXT 
done

这将起作用,因为bash globs loop over files in alphanumeric order

答案 3 :(得分:0)

以下内容(这将使文件保留最新的文件修改时间)

命令ls -rt * \(* \)。mp3 |而读-r文件;做mv -f&#34; $ file&#34; &#34; $ {文件/(*)/}&#34 ;;完成

或更安全:更改&#34; $ {file /(*)/}&#34; to&#34; $ {file%(*)。mp3} .mp3&#34;