在 Bash 中将文件夹结构展平为文件名

在 Bash 中将文件夹结构展平为文件名

我正在尝试转换以下结构的文件:

foldera/folderb/filec.png

到:

foldera_folderb_filec.png

我已经完成了一半:

 find . -type f -name "*.png" | sed 's@^./@@g;s@/@-@g'

它基本上转换了名称结构。但是,它还没有进行复制。此时我陷入了困境。我该如何扩展脚本以实际执行复制操作?

答案1

这可能对你有用:

find . -type f -name "*.png" | sed 'h;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh

答案2

这对我来说很有效。它消除了 ._ 前缀,但其他方面与potong 的回答

find . -type f -name "*" | sed 's/$/"/;s/^/"/;h;s/^...//;s/^/"/;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh

答案3

find -type f -name '*.png' -printf '%P\0' | \
while read -d $'\0' i ; do cp "$i" "${i////_}" ; done

在哪里:

  • %P告诉find省略前导./

  • \0告诉find使用字符作为分隔符来打印路径ASCII NUL(这应该可以避免出现问题奇怪的姓名)

  • -d $'\0'告诉bash使用正确的分隔符来读取路径;

  • ${i////_}告诉bash用 替换路径中/出现的每一个 。_

警告:

该管道可能涉及文件覆盖,请确保采取适当的预防措施。

答案4

上面的一些答案非常好,但是为了以防万一,我也会把我的答案也放上去。

这只会echo输出以下mv命令:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} +

这会将命令直接echo输出mv到剪贴板中:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} + | pbcopy

[小心]这将立即mv为您运行命令:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; eval "mv ${x// /\ } ${y////-}"; done' {} +

相关内容