0

Here I found a nice way to extract basename from path with awk:

awk 'BEGIN{ var="Z:\201708021541\file name with spaces.123"; n=split(var,a,/\//); print a[n]}'

but for backslashes it does not work as the characters seem to become escaped, e.g. the output of the above looks:

Z:�708021541
            ile name with spaces.123

Now, is there any way to get around in awk? The paths are listed in a file and I cannot (do not want) to preprocess all the files to escape \, so I wonder is there a way to tell awk "do not escape"?

atapaka
  • 541

1 Answers1

1

Assuming that you are trying to find the filename portion of a Windows pathname containing backslashes...

pathname='Z:\201708021541\file name with spaces.123'
filename=$(basename "${pathname//\\//}")

printf '%s\n' "$filename"

This will print

file name with spaces.123

if run in bash.

The parameter substitution ${pathname//\\//} replaces all backslashes with forward slashes in the value of $pathname, which means that the standard basename utility can work on it. The basename utility does not care that the path starts with Z: (it believes that this is the name of a directory).

Alternatively (shorter, and more portable):

pathname='Z:\201708021541\file name with spaces.123'
filename=${pathname##*\\}

printf '%s\n' "$filename"

Here, ${pathname##*\\} will remove everything up to the last backslash in $pathname. This parameter substitution is standard, whereas the one used in the first variation will only work in certain shells.


Using awk:

printf '%s\n' "$pathname" | awk '{ sub(".*\\\\", "", $0); print }'

The four backslashes are two backslashes escaped once each, because reasons.

Using sed:

printf '%s\n' "$pathname" | sed 's/.*\\//'

Both the awk and sed solutions work exactly the same way. They substitute everything up to (and including) the last backslash with an empty string.

Kusalananda
  • 333,661