ファイル名から数字を抽出

ファイル名から数字を抽出

次のモデルに従ったファイル名があります:

 1.raw_bank_details_211.trg
 2.raw_bank_details_222.trg

cutUnix のコマンドを使用して上記の文字列を切り取り、文字列から値を取得し211222エコーする必要があります。

私はすでに grep を使用していますgrep -o -E '[0-9]+'が、これに代わるものが必要です。

答え1

のような単純なツールではなく、標準的なテキスト処理ツールを使用する方がよいでしょうcut

以下にいくつかの方法を示します。


を使用するとawk_または で.区切られた最後から 2 番目のフィールドを取得できます。

awk -F '[_.]' '{print $(NF-1)}' file.txt

grepPCRE ( -P) の場合:

grep -Po '\d+(?=[^_]*$)' file.txt
  • -o一致した部分のみを取得します

  • \d+1つ以上の数字に一致する

  • ゼロ幅の正の先読みは、行の最後まで(?=[^_]*$)何も続かないことを保証する。_


sed

sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
  • .*_最後まですべて一致_

  • ([[:digit:]]+)必要な数字と一致し、キャプチャされたグループに入れます

  • .*残りと一致する

  • 置換では、捕捉されたグループのみ\1が使用される。


の場合、とperl同じロジックになりますsed

perl -pe 's/.*_(\d+).*/$1/' file.txt 

を使用する必要がある場合はcut、2 つの手順で実行し、最初に_分離された 4 番目のフィールドを取得し、次に.分離された 1 番目のフィールドを取得します。

cut -d_ -f4 file.txt | cut -d. -f1

フィールド番号をハードコードする必要があるため、これはお勧めできません。


文字列の場合は、シェル パラメータ展開を使用して実行します。

% str='1.raw_bank_details_211.trg'

% str=${str##*_} 

% echo "${str%%.*}"
211

構文を使用しwhileて各行を変数に入れてこれを行うこともできますが、大きなファイルの場合は遅くなります。また、代わりに_.を として使用し、必要に応じてIFSハードコードされたフィールド ( など) を取得することもできます。cut


例:

% cat file.txt                          
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg

% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222

% grep -Po '\d+(?=[^_]*$)' file.txt         
211
222

% sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
211
222

% perl -pe 's/.*_(\d+).*/$1/' file.txt 
211
222

% cut -d_ -f4 file.txt | cut -d. -f1
211
222

答え2

cutは、そのためのツールとしては適切ではありません。ファイル名などの短い文字列を操作するには、可能な限りシェルの文字列操作機能を使用してください。すべてのsh型シェル¹(sh、dash、bash、ksh、zsh、…)には、変数置換の一部として基本的な文字列操作機能があります。たとえば、ダッシュマニュアル「パラメータ拡張」の下で、パターンに一致する最短/最長のプレフィックス/サフィックスを削除できます。

ファイル名の最後の数字のシーケンスが必要なので、次のようになります。

  1. 最後の桁まですべてを削除して、数値以外の接尾辞を決定します。
  2. その接尾辞を削除します。
  3. 最後の非数字まですべてを削除します。
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"

¹一部の POSIX 以前の Bourne シェルを除きますが、それらについては気にする必要はありません。

関連情報