2017-11-11 157 views
1

想象我有一个像下面防止回声

a/b/c_d.e
a/b/d.f

我想裂伤的文件名,这样的路径分隔符成为_文件夹/文件结构和文件夹之间文件是一个-,然后这是前缀到文件夹位置。

a/b/a_b-c_d.e
a/b/a_b-d.f

我到目前为止有:

find . -type f -name *.c -exec sh -c "echo -n { {} | xargs dirname }; echo -n "/"; realpath --relative-to="$PWD" "{}" | tr '/' '_'" \;

将输出

./src/ucd-tools/src /src_ucd-tools_src_proplist.c

看来第一echo -n是添加新的林es,但如果我手动运行echo -n "Hello"它按预期工作,没有新行。

+1

您正在运行'sh',不'bash'和'-n'只是另一个字符串与POSIX'回声打印',而不是一面旗帜。改用'printf'/''。 – chepner

回答

4

如果你使用的是bash 4,那么在shell本身就有你需要的所有东西。无需使用外部工具,如find

这可能是一行代码。

$ shopt -s globstar  # This requires bash 4. Lets you use "**" 
$ for f in **; do test -f "$f" || continue; d=${f%/*}; echo mv "$f" "$d/${d//\//_}-${f##*/}"; done 

爆发以方便您阅读:

for f in **; do      # recurse through directories, 
    test -f "$f" || continue   # skipping anything that isn't a file 
    d=${f%/*}       # capture the directory... 
    mv -- "$f" "$d/${d//\//_}-${f##*/}" # and move the file. 
done 

mv行中的 “目标” 是由以下内容组成:

  • $d - 原目录(因为文件呆在同一个地方)
  • ${d//\//_} - 使用参数扩展来替换所有的斜杠un derscores
  • ${f##*/} - 去掉dirname,所以这只是文件名而已。
+0

OP没有说明正在使用的文件名列表是什么,但请注意,如果使用OP作为示例,覆盖数据存在危险(可能很小),其中有文件'./src/ucd_tools/src/proplist.c'和'。/ src/ucd/tools/src/proplist.c',你会盲目地尝试移动到相同的目标名称。 – chepner

+0

这太神奇了,非常感谢。 –

0

只是使用printf。它基本上像echo,但它不打印新的生产线,例如:

computer:~user$echo "hello, world" 
hello, world 
computer:~user$printf "hello, world" 
hello, worldcomputer:~user$echo "hello, world"