ここパスからデフォルト名を抽出する良い方法を見つけましたawk
。
awk 'BEGIN{ var="Z:\201708021541\file name with spaces.123"; n=split(var,a,/\//); print a[n]}'
しかし、バックスラッシュの場合、文字がエスケープされているように見えるため、機能しません。たとえば、上記の出力は次のようになります。
Z:�708021541
ile name with spaces.123
今awkをバイパスする方法はありますか?パスがファイルにリストされており、エスケープするためにすべてを前処理することはできません(不要)。\
それで、awkに「エスケープしないでください」と言う方法があるかどうか疑問に思います。
答え1
バックスラッシュを含むWindowsパス名のファイル名部分を見つけようとしているとします。
pathname='Z:\201708021541\file name with spaces.123'
filename=$(basename "${pathname//\\//}")
printf '%s\n' "$filename"
これは印刷されます
file name with spaces.123
で実行している場合bash
。
パラメータ置換は、${pathname//\\//}
値のすべてのバックスラッシュをスラッシュで置き換えます$pathname
。これは、標準basename
ユーティリティがそれを処理できることを意味します。ユーティリティbasename
はパスの先頭に気にしませんZ:
(ディレクトリ名だと思います)。
または(より短く、移植性が高い):
pathname='Z:\201708021541\file name with spaces.123'
filename=${pathname##*\\}
printf '%s\n' "$filename"
ここでは、${pathname##*\\}
最後のバックスラッシュの前の内容がすべて削除されます$pathname
。このパラメータ置換は標準ですが、最初の変形で使用されたパラメータ置換は一部のシェルでのみ機能します。
使用awk
:
printf '%s\n' "$pathname" | awk '{ sub(".*\\\\", "", $0); print }'
これらの4つのバックスラッシュは、理由のために2つのバックスラッシュにそれぞれ1回エスケープされます。
使用sed
:
printf '%s\n' "$pathname" | sed 's/.*\\//'
awk
そして、sed
ソリューションはまったく同じように動作します。最後のバックスラッシュまでのすべての項目を空の文字列に置き換えます。