`

Bash字符串处理(与Java对照) - 24.文件路径字符串的处理(路径处理)

阅读更多

Bash字符串处理(与Java对照) - 24.文件路径字符串的处理(路径处理)

In Java

File类:得到指定文件的文件名、文件所在目录

import java.io.File;

public class TestFile {

        public static void main(String[] args) {
                String filename = "hello.txt";
                // 创建File对象
                File file = new File(filename);
                // 得到文件名
                String name = file.getName();
                System.out.println("name=" + name);
                // 得到目录
                String dir = file.getParent();
                System.out.println("dir=" + dir);
        }
}
 

[root@jfht params]# javac TestFile.java && java TestFile
name=hello.txt
dir=null

问题来了,第二行打印null,无法得到文件所在目录。

 

import java.io.File;
import java.io.IOException;

public class TestFile {

        public static void main(String[] args) throws IOException {
                String filename = "hello.txt";
                // 创建File对象
                File file = new File(filename);
                // 得到路径
                String path = file.getPath();
                System.out.println("path=" + path);
                // 得到文件名
                String name = file.getName();
                System.out.println("name=" + name);
                // 得到目录
                String dir = file.getParent();
                System.out.println("dir=" + dir);
                // 得到绝对路径
                String apath = file.getAbsolutePath();
                System.out.println("apath=" + apath);
                // 得到规范路径
                String cpath = file.getCanonicalPath();
                System.out.println("cpath=" + cpath);
                // 得到绝对文件对象
                File file2 = file.getAbsoluteFile();
                String dir2 = file2.getParent();
                System.out.println("dir2=" + dir2);
                // 得到规范文件对象
                File file3 = file.getCanonicalFile();
                String dir3 = file3.getParent();
                System.out.println("dir3=" + dir3);
        }
}

 

[root@jfht params]# javac TestFile.java && java TestFile
path=hello.txt
name=hello.txt
dir=null
apath=/opt/shtools/params/hello.txt
cpath=/opt/shtools/params/hello.txt
dir2=/opt/shtools/params
dir3=/opt/shtools/params
[root@jfht params]#

 

如果把filename改成 "./hello.txt",执行结果如下:

[root@jfht params]# javac TestFile.java && java TestFile
path=./hello.txt
name=hello.txt
dir=.
apath=/opt/shtools/params/./hello.txt
cpath=/opt/shtools/params/hello.txt
dir2=/opt/shtools/params/.
dir3=/opt/shtools/params
[root@jfht params]#

 

如果把filename改成 "../hello.txt",执行结果如下:

[root@jfht params]# javac TestFile.java && java TestFile
path=../hello.txt
name=hello.txt
dir=..
apath=/opt/shtools/params/../hello.txt
cpath=/opt/shtools/hello.txt
dir2=/opt/shtools/params/..
dir3=/opt/shtools
[root@jfht params]#

 

现在,总结一下:

得到文件所在目录的有效方法是:

file.getCanonicalFile().getParent();

 

javadoc File.getCanonicalPath() & File.getCanonicalFile() 写道
getCanonicalPath

public String getCanonicalPath() throws IOException

返回抽象路径名的规范路径名字符串。

规范路径名是绝对路径名,并且是惟一的。规范路径名的准确定义与系统有关。如有必要,此方法首先将路径名转换成绝对路径名,这与调用 getAbsolutePath() 方法的效果一样,然后用与系统相关的方式将它映射到其惟一路径名。这通常涉及到从路径名中移除多余的名称(比如 "." 和 "..")、分析符号连接(对于 UNIX 平台),以及将驱动器名转换成标准大小写形式(对于 Microsoft Windows 平台)。

表示现有文件或目录的每个路径名都有一个惟一的规范形式。表示非存在文件或目录的每个路径名也有一个惟一的规范形式。非存在文件或目录路径名的规范形式可能不同于创建文件或目录之后同一路径名的规范形式。同样,现有文件或目录路径名的规范形式可能不同于删除文件或目录之后同一路径名的规范形式。

返回:
表示与此抽象路径名相同的文件或目录的规范路径名字符串
抛出:
IOException - 如果发生 I/O 错误(可能是因为构造规范路径名需要进行文件系统查询)
SecurityException - 如果无法访问所需的系统属性值,或者存在安全管理器,且其 SecurityManager.checkRead(java.io.FileDescriptor) 方法拒绝对该文件进行读取访问
从以下版本开始:
JDK1.1

getCanonicalFile

public File getCanonicalFile() throws IOException

返回此抽象路径名的规范形式。等同于 new File(this.getCanonicalPath()())。

返回:
表示与此抽象路径名相同的文件或目录的规范路径名字符串
抛出:
IOException - 如果发生 I/O 错误(可能是因为构造规范路径名需要进行文件系统查询)
SecurityException - 如果无法访问所需的系统属性值,或者存在安全管理器,且其 SecurityManager.checkRead(java.io.FileDescriptor) 方法拒绝对该文件进行读取访问
从以下版本开始:
1.2

 

In Bash

当前执行脚本的文件名

在bash中,位置参数$0就是调用脚本时的文件名。

 

Bash脚本 dollar0.sh

#!/bin/sh

echo "$0"

# END.
 

[root@jfht params]# ./dollar0.sh
./dollar0.sh
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh

[root@jfht params]# sh dollar0.sh
dollar0.sh

[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh 
/opt/shtools/params/dollar0.sh
[root@jfht params]#

 

注意:网上有文章如下所说,显然是不太正确的。

http://songzhangzhang.blog.163.com/blog/static/6940198120116201641361/ 写道
在bash脚本中$0是该脚本文件的全路径文件名,不管脚本的调用方式是直接指定具体文件路径还是把脚本文件所在目录放在PATH环境变量中。
 

当前执行脚本所在目录

dirname命令可以得到指定文件的目录部分。

info dirname 写道
18.2 `dirname': Strip non-directory suffix from a file name
===========================================================

`dirname' prints all but the final slash-delimited component of a
string (presumably a file name). Synopsis:

dirname NAME

If NAME is a single component, `dirname' prints `.' (meaning the
current directory).

The only options are `--help' and `--version'. *Note Common
options::.

An exit status of zero indicates success, and a nonzero value
indicates failure.

Examples:

# Output "/usr/bin".
dirname /usr/bin/sort

# Output ".".
dirname stdio.h

 

对前面的脚本进行修改,增加对执行脚本文件所在目录的打印输出。

#!/bin/sh

echo "$0"
echo "$(dirname "$0")"

# END.

 

[root@jfht params]# ./dollar0.sh
./dollar0.sh
.
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
/opt/shtools/params
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh
../params
[root@jfht params]# sh dollar0.sh
dollar0.sh
.

[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh 
/opt/shtools/params/dollar0.sh
/opt/shtools/params
[root@jfht params]#

 

得到指定目录的全路径目录

从上面的例子看出,dirname不一定得到全路径目录,随着调用方式的不同会有不同的结果。

 

对前面的dollar0脚本进行改进,增加realdir函数,用于打印指定目录的全路径。

#!/bin/sh

echo "$0"
echo "$(dirname "$0")"

fulldir()
{
        (cd "$1" && pwd)
}

echo "$(fulldir "$(dirname "$0")")"

# END.
 

[root@jfht params]# ./dollar0.sh
./dollar0.sh
.
/opt/shtools/params
[root@jfht params]# $(pwd)/dollar0.sh 
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
[root@jfht params]# ../params/dollar0.sh      
../params/dollar0.sh
../params
/opt/shtools/params
[root@jfht params]# sh dollar0.sh          
dollar0.sh
.
/opt/shtools/params
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
/opt/shtools/params
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh 
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
[root@jfht params]#

 

得到指定文件的文件名部分

basename命令可以得到指定文件的文件名称部分。

info basename 写道
18.1 `basename': Strip directory and suffix from a file name
============================================================

`basename' removes any leading directory components from NAME.
Synopsis:

basename NAME [SUFFIX]

If SUFFIX is specified and is identical to the end of NAME, it is
removed from NAME as well. `basename' prints the result on standard
output.

The only options are `--help' and `--version'. *Note Common
options::. Options must precede operands.

An exit status of zero indicates success, and a nonzero value
indicates failure.

Examples:

# Output "sort".
basename /usr/bin/sort

# Output "stdio".
basename include/stdio.h .h

 

当前执行脚本的全路径文件名

继续对上面的脚本进行改进,增加fullname函数来得到指定文件的全路径。

#!/bin/sh

echo "$0"
echo "$(dirname "$0")"

# usage: fulldir <dir>
fulldir()
{
        (cd "$1" && pwd)
}

echo "$(fulldir "$(dirname "$0")")"

# usage: fullname <dirname_ro_filename>
fullname()
{
        local dir=$(dirname "$0")
        local name=$(basename "$0")
        echo "$(cd "$dir" && pwd)/$name"
}

echo "$(fullname "$0")"

# END.

 

[root@jfht params]# ./dollar0.sh 
./dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# $(pwd)/dollar0.sh
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# ../params/dollar0.sh
../params/dollar0.sh
../params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# sh dollar0.sh
dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# PATH=.:$PATH dollar0.sh
./dollar0.sh
.
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]# PATH=$(pwd):$PATH dollar0.sh  
/opt/shtools/params/dollar0.sh
/opt/shtools/params
/opt/shtools/params
/opt/shtools/params/dollar0.sh
[root@jfht params]#

 

补充:echo $PWD与pwd

在bash中,pwd命令与echo $PWD得到的结果是一样的,因此上面的脚本也可以如下编写。

#!/bin/sh

echo "$0"
echo "$(dirname "$0")"

# usage: fulldir <dir>
fulldir()
{
        (cd "$1" && echo "$PWD")
}

echo "$(fulldir "$(dirname "$0")")"

# usage: fullname <dirname_ro_filename>
fullname()
{
        local dir=$(dirname "$0")
        local name=$(basename "$0")
        echo "$(cd "$dir" && echo "$PWD")/$name"
}

echo "$(fullname "$0")"

# END.
 

 

本文链接:http://codingstandards.iteye.com/blog/1164909   (转载请注明出处)

返回目录:Java程序员的Bash实用指南系列之字符串处理(目录) 

上节内容:Bash字符串处理(与Java对照) - 23.字符串替换、子串删除、子串截取

下节内容:Bash字符串处理(与Java对照) - 25.字符串分割(成数组)

 

6
3
分享到:
评论
1 楼 superlittlefish 2011-10-31  
学习了. 感谢楼主.
期待能够有更加深入的文章, 感觉现在的很多东西太基础了.

相关推荐

    mysql-connector-java-5.1.40.tar.gz

    这个压缩包包含了运行Java应用与MySQL数据库进行交互所需的类库和其他相关文件。 在Linux环境中处理这个压缩包,首先需要将其上传到系统中。这通常通过FTP、SCP或SFTP等文件传输协议完成。上传完成后,我们可以在一...

    openjdk-17.0.2(openjdk-17.0.2_macos-aarch64_bin.tar.gz)

    3. **文本块(Text Blocks)**:Java 13 引入的新语法特性,使得多行字符串的编写更加直观,减少了转义字符的困扰。 4. **记录类(Record Classes)**:Java 14 添加的记录类简化了创建不可变数据对象的过程,自动...

    libaio-devel-0.3.106(i386 x86_64)

    在给定的压缩包中,有两个不同的 RPM 文件,分别是针对 i386(32位)架构的 libaio-devel-0.3.106-3.2.i386.rpm 和针对 x86_64(64位)架构的 libaio-devel-0.3.106-3.2.x86_64.rpm。这意味着无论你是在32位还是64位...

    mysql-connector-java-8.0.13.jar

    MySQL Connector/J 8.0.13 是MySQL数据库与Java应用程序之间的重要桥梁,它是Oracle官方提供的用于Java平台的MySQL驱动程序。这个jar包允许开发者在Java应用中执行SQL语句,进行数据的读取、写入和管理MySQL数据库。...

    fontconfig-2.13.0-4.3.el7.x86_64.zip

    在Linux系统中,字体管理是实现正确显示各种字符集,包括中文字符,的关键部分。`fontconfig`是一个开源的字体配置库,它负责管理和查找系统中的字体,为应用程序提供统一的接口来处理字体问题。在没有互联网连接...

    Java-JDK-11.0.8(Windows &amp;amp; Mac os) 下载

    在Mac上,安装完成后通常需要手动配置环境变量,通过修改"~/.bash_profile"或"~/.zshrc"文件,添加类似"export JAVA_HOME=/path/to/jdk11.0.8"的语句,确保系统可以找到Java命令。 Java 11作为长期支持(LTS)版本...

    perl-5.26.1.tar.gz

    - 支持Unicode 9.0,增强了字符串和正则表达式的处理能力。 - `List::Util`模块新增了一些实用函数,如`minmax`,方便处理列表数据。 - 错误消息和诊断信息的改进,提高了调试的便利性。 Perl语法特点: - 采用C...

    jdk-11.0.16.1-linux-x64-bin.tar

    标题中的"jdk-11.0.16.1-linux-x64-bin.tar"是一个针对Linux操作系统的64位Java Development Kit(JDK)的压缩文件,版本为11.0.16.1。这个文件是Oracle JDK的特定版本,用于在Linux环境下开发和运行Java应用程序。 ...

    redis-3.2.8.tar.gz和tcl8.6.1-src.tar.gz

    对于Redis的进一步学习,了解其数据类型(如字符串、哈希、列表、集合和有序集合)以及命令是非常重要的。例如,`SET`用于设置键值,`GET`用于获取键的值,`LPUSH/RPOP`用于操作列表,`HSET/HGET`处理哈希等。此外,...

    rlwrap-0.37.tar.gz

    总的来说,rlwrap提供了一种更高效、更易用的方式来与sqlplus交互,尤其是在处理字符编码问题时。对于需要频繁使用sqlplus的数据库管理员和开发者来说,rlwrap是一个非常实用的工具。通过正确配置和使用rlwrap,可以...

    protoc.exe和protobuf-java-2.5.0.jar集合

    当你在Java项目中使用protobuf时,你需要将这个JAR文件添加到你的类路径中。这个特定版本(2.5.0)可能已经有些过时,但仍然适用于许多现有项目。较新的版本可能会提供更多的功能和性能优化。 protobuf的主要优点...

    msys-2.0.dll库文件msys-2.0.dll库文件msys-2.0.dll库

    4. **字符集转换**:msys-2.0.dll还处理字符编码问题,比如在UTF-8和Windows默认的ANSI编码之间进行转换。 然而,在使用过程中,msys-2.0.dll可能会遇到一些常见问题: 1. **丢失或损坏**:如果msys-2.0.dll文件...

    apache-tomcat-7.0.70.tar.gz

    尽管Tomcat不是完整的Java EE应用服务器,但它与Java EE的其他组件(如EJB)可以通过与其他服务器(如JBoss或Glassfish)集成来支持。 **Linux系统**: Linux是一种自由和开放源代码的操作系统,广泛应用于服务器...

    apache-tomcat-7.0.52.tar.gz+nginx-1.8.0.tar.gz

    Apache Tomcat是一个开源的应用服务器,主要用于运行Java Servlets和JavaServer Pages (JSP),而Nginx则是一个高性能的Web服务器和反向代理服务器,以其高效的处理静态内容和高并发能力而著名。 描述中提到,在...

    apache-tomcat-8.5.38.tar.gz

    Apache Tomcat是一个开源的软件应用服务器,主要用于运行Java Servlets和JavaServer Pages(JSP)。在本案例中,我们讨论的是版本8.5.38的Tomcat,它被打包成`.tar.gz`的格式。`.tar.gz`是Linux和Unix环境中常用的...

    tftp-server-0.42-3.1.i386.rpm.

    《TFTP服务器在RHEL5系统中的应用与配置详解》 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种轻量级的文件传输协议,常用于设备初始化、固件更新、网络诊断等场景。在RHEL5(Red Hat Enterprise...

    arm-linux-gcc-4.4.3.tar.gz

    为了让系统知道新的交叉编译器的位置,需要在用户或系统的`~/.bashrc`或`/etc/bash.bashrc`文件中添加以下内容: ```bash export CC=/usr/local/arm-linux-gcc-4.4.3/bin/arm-linux-gcc export CXX=/usr/local/arm-...

    libpng-1.6.37.tar.gz

    libpng是一个开源的PNG(Portable Network Graphics)图像处理库,广泛应用于各种操作系统和编程语言环境中,用于读取、写入和处理PNG图像文件。PNG是一种无损压缩的位图格式,提供透明度支持和颜色空间选择,是Web...

    fonts-chinese-3.02-12.el5.noarch.rpm和fonts-ISO8859-2-75dpi-1.0-17.1.noarch.rpm

    同时,对于需要处理中欧语言的环境,ISO 8859-2字体的提供则至关重要,因为它包含了那些区域的特殊字符,使得文本可以正确地被识别和打印。 总的来说,这两个rpm包提供了必要的字体资源,增强了CentOS系统对中文和...

    jdk-11.0.18-linux-aarch64-bin.tar.gz

    5. **文本块(Text Blocks)**:Java 11引入了文本块(多行字符串字面量)的预览特性,允许程序员方便地处理多行文本,减少字符串连接操作和转义字符的使用。 6. **其他语言特性和API增强**:包括对TLS协议的更新、...

Global site tag (gtag.js) - Google Analytics