首页 > 解决方案 > Bash 递归删除前导下划线

问题描述

我正在尝试从某些 scss 文件中递归删除前导下划线。这就是我所拥有的。

find . -name '*.scss' -print0 | xargs -0 -n1 bash -c 'mv "$0" `echo $0 | sed -e 's:^_*::'`'

当我在特定目录中时,这非常有效:

for FILE in *.scss; do mv $FILE `echo $FILE | sed -e 's:^_*::'`; done

我在查找中做错了什么?

标签: bashfind

解决方案


由于起点是.,所有find打印的路径都以点开头。因此^_*不匹配任何内容并sed返回其输入不变。

我不会sed打扰xargs

下面的脚本适用于任何findsh没有被严重破坏的脚本,并且可以正确处理中间带下划线的文件名。

find . -name '_*.scss' -exec sh -c '
for fp; do                # pathname
  fn=${fp##*/}            # filename
  fn=${fn#"${fn%%[!_]*}"} # filename w/o leading underscore(s)
  echo mv "$fp" "${fp%/*}/$fn"
done' sh {} +

bash 中一个不太便携但更短且更清洁的替代方案如下所示:

shopt -s globstar extglob nullglob

for fp in ./**/_*.scss; do
  echo mv "$fp" "${fp%/*}/${fp##*/+(_)}"
done

echo如果输出看起来不错,则丢弃。


推荐阅读