Extract file name from path in awk program

I have an awk script and I have passed a CSV file to it.

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

What am I doing is to get FILENAME within script.awk. FILENAME gives me the whole path. As I am in awk I cannot use basename FILENAME.

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

I have tried with this within script.awk

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

but I cannot execute this within script.awk. How can I get asgd.csv within an awk program?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Several options:

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

Or:

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

Note that those implementations of basename should work for the common cases, but not in corner cases like basename /path/to/x/// where they return the empty string instead of x or / where they return the empty string instead of /, though for regular files, that should not happen.

The first one will not work properly if the file paths (up to the last /) contain sequences of bytes that don’t form valid characters in the current locale (typically this kind of thing happens in UTF-8 locales with filenames encoded in some 8 bit single byte character set). You can work around that by fixing the locale to C where every sequence of byte form valid characters.

Method 2

Try this awk one-liner,

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

Method 3

On the systems where basename command is available, one could use awk‘s system() function or expression | getline var structure to call external basename command. This can help accounting for corner cases mentioned in Stephane’s answer.

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

Method 4

Use Awk’s Split Function

One way to do this is to use the split function. For example:

awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' /path/to/file

This even works on multiple files. For example:

$ awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' 
      /etc/passwd /etc/group
passwd
group

Method 5

the best way to export it from input CSV or directly from input file path you can reverse it , then get 1 column and then again reverse it.

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

or simply

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x