awkとWindowsのパスバックスラッシュエスケープ文字

awkとWindowsのパスバックスラッシュエスケープ文字

ここパスからデフォルト名を抽出する良い方法を見つけました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ソリューションはまったく同じように動作します。最後のバックスラッシュまでのすべての項目を空の文字列に置き換えます。

関連情報