
次のようなファイルパス名があります
/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz
6 桁の201906
数字だけを取得して印刷しようとしています。 試してみましたsed
がawk
失敗しました。
答え1
これらがシステム上の実際のファイルであると仮定すると、シェル ループを使用して、ディレクトリ内の_
一致する各ファイルのファイル名の最初の部分の前部分を簡単に抽出できます。*_*.tar.tgz
/dbfs/mnt/dlg2stage/foldername/backupname
for pathname in /dbfs/mnt/dlg2stage/foldername/backupname/*_*.tar.tgz; do
name=$( basename "$pathname" )
printf '%s\n' "${name%%_*}"
done
このbasename
ユーティリティは、パス名のファイル名部分を返します。 示されている例では、文字列が201906_load_1_20210623-151602.tar.tgz
変数 に割り当てられますname
。 を使用しても同じことを行うことができますname=${pathname##*/}
(このパラメータ展開により、 内の文字列の最初のセクションが$pathname
、最後の まで削除されます/
)。
パラメータ展開により、値 から${name%%_*}
最も長い末尾の部分文字列の一致が削除されます。示されている例では、最初の文字とその右側にあるすべての文字が削除され、部分文字列 が残ります。これは を使用して印刷されます。_*
$name
_
201906
printf
答え2
とzsh
:
file=/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz
set -o extendedglob # for (#c6)
first_6_digits_of_file_tail=${(M)${file:t}[0-9](#c6)}
どこ${file:t}
でしっぽファイル(のベース名)の${(M)var#pattern}
先頭にあるパターンに一致する部分を返します。$var
M
POSIX では、以下を使用できます。
first_6_digits_of_file_tail=$(
LC_ALL=C expr "/$file" : '.*/\([0-9]\{6\}\)[^/]*/*$'
)
LC_ALL=C
ユーザーのロケールを無視し、すべてのバイトを文字 (ほとんどのシステムの ASCII に従って最初の 128 文字、/ および 0123456789 の数字を含む) と見なすため、.
と が[^/]
バイトと一致することが保証され、[0-9]
には 0123456789 のみが含まれます。zsh
範囲はコードポイントに基づいており、zsh は有効な文字の一部を形成しない各バイトを文字であるかのように見なします。
先頭に追加することで、演算子で始まるか演算子のように見える/
値に関する問題を回避し、正規表現で期待されるとおりに文字列に少なくとも 1 つ含まれていることを保証します。$file
-
expr
/
またはのベース名が である、または zsh を使用するソリューションと同じ動作を得るために、最後の except/
の後に を使用することはできません。/XXXXXX
basename
$file:t
/foo/bar/
/foo/bar////
bar
一致するものがない場合だけでなく、6 桁のシーケンスが 0 を表す場合 ( のように/path/to/000000_whatever
) にも、false / 失敗の終了ステータスが返されることに注意してください。
答え3
与えられたパス文字列を印刷したいだけだと思います201906
。この例では、6 桁の数字は次のようになります。先頭にスラッシュがある最初の6桁。
コマンドを読みやすくするために、パスを変数に入れています。
% path_str='/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz'
% echo $path_str | sed 's/.*\/\([0-9]\{6\}\).*/\1/'
201906
マッチと交換をどうやって構築したかを説明しますsed:
\/[0-9]\{6\}
: スラッシュと6桁の数字に一致します\/\([0-9]\{6\}\)
: は同じですが、今はキャプチャグループまたはサブ式(スラッシュはキャプチャグループに含まれません).*\/\([0-9]\{6\}\).*
: は前後のすべてに一致するので...全行\1
: 行全体が一致している場合は、初め(そして唯一の)キャプチャグループを使用して、行全体を最初の6桁のみに置き換えます。