Linux Bash - 如何删除文件夹中包含的文件的部分文件名

时间:2016-09-05 21:46:31

标签: bash replace sed find

我有几个包含文件的目录,这些文件的名称包含文件夹的名称。 例如:

one/berg - one.txt
two/tree - two.txt
three/water - three.txt

我希望如此:

one/berg.txt
two/tree.txt
three/water.txt

我尝试使用sed命令,find命令,命令等。 我失败了必须找到一种方法来获得它。

你可以帮助我吗?谢谢

2 个答案:

答案 0 :(得分:1)

简短,如果你有GNU find:

find . -name '* - *.*' -execdir bash -c '
  for file; do
    ext=${file##*.}
    mv -- "$file" "${file%% - *}.${ext}"
  done
' _ {} +
  • -execdir在找到每组文件的目录中执行给定的命令,因此不必担心目录名称。
  • for file; do是写for file in "$@"; do的简短方法。
  • ${file##*.}扩展为$file的内容,其中包含最后一个.已移除的内容(因此,它会扩展到文件的扩展名)。
  • "${varname%% - *}"扩展为变量varname的内容,并在<space><dash><space>之后删除所有内容。
  • 在成语-exec bash -c '...' _ {} +中(与-execdir一样),传递给bash -c的脚本以_作为$0运行,所有文件由find在随后的职位中。

答案 1 :(得分:0)

在sed的帮助下,这是一种方法:

#!/bin/bash

find -type f -print0 | \
    while IFS= read -r -d '' old_path; do
        new_path="$(echo "$old_path" | sed -e 's|/\([^/]\+\)/\([^/]\+\) - \1.\([^/.]\+\)$|/\1/\2.\3|')"
        if [[ $new_path != $old_path ]]; then
            echo mv -- "$old_path" "$new_path"
          # ^^^^ remove this "echo" to actually rename the files
        fi
    done

您必须cd到包含所有这些文件的顶级目录才能执行此操作。此外,它会保留echo,因此它实际上不会重命名文件。运行一个以查看您是否喜欢其输出,如果您喜欢,请删除echo并再次运行。

基本思想是我们迭代所有文件,对于每个文件,我们尝试查找文件是否与给定模式匹配。如果是,我们重命名它。该模式检测(并捕获)路径的倒数第二个组件,并将路径的最后一个组件分为3个部分:前缀,后缀(必须与前一个路径组件匹配)和扩展。