从 awk 程序中的路径中提取文件名

从 awk 程序中的路径中提取文件名

我有一个 awk 脚本,并且已将 CSV 文件传递​​给它。

awk -f script.awk /home/abc/imp/asgd.csv

我正在做的就是获取 FILENAME 内的script.awk. FILENAME 给了我整个路径。由于我在 awk 中,我无法使用basename FILENAME.

print FILENAME;
/home/abc/imp/asgd.csv

我已经尝试过这个script.awk

echo $FILENAME | awk -F"/" '{print $NF}'

但我无法在 内执行此操作script.awk。我怎样才能进入asgd.csvawk 程序?

答案1

几种选择:

awk '
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

或者:

awk '
  function basename(file, a, n) {
    n = split(file, a, "/")
    return a[n]
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

请注意,这些实现basename应该适用于常见情况,但不适用于极端情况,例如basename /path/to/x///返回空字符串而x不是/返回空字符串/,但对于常规文件,这种情况不应该发生。

如果文件路径(直到最后一个/)包含在当前语言环境中不形成有效字符的字节序列,第一个将无法正常工作(通常这种情况发生在文件名以某些 8 编码的 UTF-8 语言环境中)位单字节字符集)。您可以通过将语言环境固定为 C 来解决这个问题,其中每个字节序列都形成有效字符。

答案2

试试这个 awk 单行代码,

$ awk 'END{ var=FILENAME; split (var,a,/\//); print a[5]}' /home/abc/imp/asgd.csv
asgd.csv

答案3

在有命令的系统上basename,可以使用awksystem()函数或expression | getline var结构来调用外部basename命令。这可以帮助解释中提到的极端情况斯蒂芬的回答

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd

答案4

从输入 CSV 或直接从输入文件路径导出它的最佳方法是,您可以反转它,然后获取 1 列,然后再次反转它。

function getFileFromPath() {
    FileName=$1
    cat $FileName | while read Filename
    do
        echo $Filename| rev | awk -v FS='/' '{print $1}' | rev 
    done
}

或者简单地

echo $FileNamePath| rev | awk -v FS='/' '{print $1}' | rev 

相关内容