我有一个完整路径就像
的文件/a/b/c/d/filename.txt
如果我对其进行了basename
,我会得到filename.txt
。但是这个文件名并不是太独特。
因此,如果我可以将文件名提取为d_filename.txt
,即
{immediate directory}_{basename result}
如何实现此结果?
答案 0 :(得分:2)
file="/path/to/filename"
echo $(basename $(dirname "$file")_$(basename "$file"))
或
file="/path/to/filename"
filename="${file##*/}"
dirname="${file%/*}"
dirname="${dirname##*/}"
filename="${dirname}_${filename}"
答案 1 :(得分:1)
这段代码将以你运行脚本的目录开始递归搜索你的层次结构。我已经用这样的方式对循环进行编码,它将处理你抛出的任何文件名;带空格,换行符等的文件名。
*注意**:循环当前写入 不 包含此脚本所在目录中的所有文件,它只查看它下面的子目录。这样做是因为它是确保脚本在处理过程中不包含自身的最简单方法。如果由于某种原因您必须包含脚本所在的目录,则可以更改它以适应此目的。
#!/bin/bash
while IFS= read -r -d $'\0' file; do
dirpath="${file%/*}"
filename="${file##*/}"
temp="${dirpath}_${filename}"
parent_file="${temp##*/}"
printf "dir: %10s orig: %10s new: %10s\n" "$dirpath" "$filename" "$parent_file"
done < <(find . -mindepth 2 -type f -print0)
$ tree -a
.
|-- a
| |-- b
| | |-- bar
| | `-- c
| | |-- baz
| | `-- d
| | `-- blah
| `-- foo
`-- parent_file.sh
$ ./parent_file.sh
dir: ./a/b/c/d orig: blah new: d_blah
dir: ./a/b/c orig: baz new: c_baz
dir: ./a/b orig: bar new: b_bar
dir: ./a orig: foo new: a_foo
答案 2 :(得分:0)
$ FILE=/a/b/c/d/f.txt
$ echo $FILE
/a/b/c/d/f.txt
$ echo $(basename ${FILE%%$(basename $FILE)})_$(basename $FILE)
d_f.txt
答案 3 :(得分:0)
不需要调用外部命令
s="/a/b/c/d/filename.txt"
t=${s%/*}
t=${t##*/}
filename=${t}_${s##*/}
答案 4 :(得分:0)
举个例子:
/a/1/b/c/d/file.txt
/a/2/b/c/d/file.txt
限定file.txt
并避免冲突的唯一可靠方法是将整个路径构建到新文件名中,例如
/a/1/b/c/d/file.txt -> a_1_b_c_d_file.txt
/a/2/b/c/d/file.txt -> a_2_b_c_d_file.txt
如果您确定所有文件都是通用的,例如,如果您知道所有文件都位于上面/a
目录下的某个位置,则可以跳过部分开头:
/a/1/b/c/d/file.txt -> 1_b_c_d_file.txt
/a/2/b/c/d/file.txt -> 2_b_c_d_file.txt
要在每个文件的基础上实现此目的:
# file="/path/to/filename.txt"
new_file="`echo \"$file\" | sed -e 's:^/::' -e 's:/:_:g'`"
# new_file -> path_to_filename.txt
假设您希望在目录及其子目录中递归执行此操作:
# dir = /a/b
( cd "$dir" && find . | sed -e 's:^\./::' | while read file ; do
new_file="`echo \"$file\" | sed -e 's:/:_:g'`"
echo "rename $dir/$file to $new_file"
done )
输出:
rename /a/b/file.txt to file.txt
rename /a/b/c/file.txt to c_file.txt
rename /a/b/c/e/file.txt to c_e_file.txt
rename /a/b/d/e/file.txt to d_e_file.txt
...
以上是高度可移植的,基本上可以在sh
的任何变体的任何Unix系统上运行(包含bash
,ksh
等。)