我有一个文件(比如说叫list.txt
),其中包含文件的相对路径,每行一个路径,即像这样:
foo/bar/file1
foo/bar/baz/file2
goo/file3
我需要编写一个 bash 脚本,一次处理一条路径,在最后一个斜杠处拆分它,然后启动另一个进程,将路径的两部分作为参数提供给它。到目前为止,我只有循环部分:
for p in `cat list.txt`
do
# split $p like "foo/bar/file1" into "foo/bar/" as part1 and "file1" as part2
inner_process.sh $part1 $part2
done
如何拆分?这在路径没有斜杠的退化情况下是否有效?
使用basename
和dirname
,这就是你所需要的。
part1=$(dirname "$p")
part2=$(basename "$p")
一种适当的 100% bash 方式,对于具有空格或有趣符号的文件名是安全的(前提是inner_process.sh
正确处理它们,但那是另一回事):
while read -r p; do
[[ "$p" == */* ]] || p="./$p"
inner_process.sh "${p%/*}" "${p##*/}"
done < list.txt
它不会为每个文件分叉dirname
和basename
(在子外壳中)。
[[ "$p" == */* ]] || p="./$p"
行在这里以防万一$p
不包含任何斜杠,然后它会在前面加上./
。
有关%
和##
符号的详细信息,请参阅 Bash 参考手册中的外壳参数扩展部分。
我从这个来源找到了一个很好的解决方案。
p=/foo/bar/file1
path=$( echo ${p%/*} )
file=$( echo ${p##*/} )
这也适用于路径中的空格!
虽然基本名称和目录确实很有帮助,但也许你和我的情况相同:
我只需要获取路径的前 N 个文件夹,我可以在任何文件夹上,例如:/home/me/folder/i/want/
、/home/me/
或 /home/me/folder/i/want/folder/i/dont/want/
。
所以我用了cut
.
这是命令只得到/home/me/folder/i/want
,无论我在哪里:
echo "/home/me/folder/i/want/folder/i/dont/want" | cut -f 1,2,3,4,5,6 -d "/"
在这里,cut通过"/"字符拆分字符串,并且仅显示第1,2[...]第6个单词。
以下是一些示例:
$ echo $PWD
/home/me/folder/i/want/folder/i/dont/want
$ echo $PWD | cut -f 1,2,3,4,5,6 -d "/"
/home/me/folder/i/want
$ cd ../../../..
$ echo $PWD
/home/me/folder/i/want
$ echo $PWD | cut -f 1,2,3,4,5,6 -d "/"
/home/me/folder/i/want
$ cd ~
echo $PWD | cut -f 1,2,3,4,5,6 -d "/"
/home/me
下面是查找文件扩展名并将其替换为 xml 的示例。
for files in $(ls); do
filelist=$(echo $files |cut -f 1 -d ".");
mv $files $filelist.xml;
done