2017-11-11 163 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"