拡張する変数を含むパターンでgrepを使用してください。

拡張する変数を含むパターンでgrepを使用してください。

テーブルファイルがあります

2e95d7582c53583fa8afb54e0fe7a2597c92cbba 1461065389 52880 temp/hello/file.txt
46c897a7aa8a641f46080b3431860bd0cd4a8f05 1461066221 207 temp/Another file.txt
83c8ce6b163ec1c615617fa0dbde9e928bc3daf4 1461056193 86112 Pictures/a photo.jpg
...

つまり、各行には40文字の16進数字が含まれ、その後にスペース、整数、スペース、整数、スペース、スペースを含めることができるファイルパスが続きます。すべての道路はユニークです。

Bashスクリプトでは、私の変数は最初の16進文字列とスペース(最初の41文字)だけを除いてファイルの行と同じ形式を持ちます。たとえば、次のようになります。

myvar="1461066221 207 temp/Another file.txt"

私の目標は探すことです。これファイルの一致行myvar 正確に最初の41文字は無視されます。そのような一致が見つかったら、変数をlineファイルの完全な行に設定したいと思います。上記の例では、line次のように設定されています。

46c897a7aa8a641f46080b3431860bd0cd4a8f05 1461066221 207 temp/Another file.txt

一致するものがない場合は、空のline文字列に設定するか、まったく設定しないでください。

私の解決策は次のとおりです(filelistファイル名)。

line=$(grep --color=never -E "^.{41}$myvar$" $filelist)

1つの問題は、拡張に特別な意味を持つ、Evenなどの$myvar特殊記号を含めることができることです。公演したい.+^$grepgrep精密myvar1行の最初の41文字を除くすべての文字と一致します。

答え1

Perlが救出に来る!

perl -ne 'BEGIN { $search = shift }
          print if /^.{41}\Q$search\E$/;
         ' -- "$myvar" "$filelist"
  • -nファイルを1行ずつ読みます。
  • BEGINブロックは、Perl変数$ searchの最初の引数で$ myvarを検索します。
  • \Q...\E内部部品の引用(参照)参照要素)。これは変数に含めることができるすべての特殊文字を処理します。シェル変数を二重引用符で囲むことを忘れないでください!

答え2

export myvar
awk 'substr($0, 42) == ENVIRON["myvar"]' < "$filelist"

答え3

これは別のアプローチです。まず 'line' を空白に設定し、次の 3 つのフィールドに一致する項目を見つけたら 'myvar' を設定します。

line=
while IFS=' ' read -r hex int1 int2 rest
do
  if [[ "$myvar" = "$int1 $int2 $rest" ]]
  then
    line="$hex $int1 $int2 $rest"
  fi
done < filelist

bashのmapfile組み込みと2番目の一時的な連想配列を使用する別のアプローチは次のとおりです。

mapfile -t < filelist # sets MAPFILE array
declare -A temparray
shopt -s extglob
for val in "${MAPFILE[@]}"
do 
  short="${val##*([^ ]) }"
  temparray[$short]="$val"
done
line=${m[$myvar]}
unset -v MAPFILE temparray val short

これは、ファイルをインデックス配列MAPFILEに入れてから繰り返します。このループは、「short」変数を行の「サフィックス」部分に設定します。 「ゼロ個以上の非空白の後に空白が続く」パターンに一致する先行値を削除し、「$」shortの連想配列値を設定します。 「を整数行(「$ val」)に置き換えます。これが*必要ですshopt -s extglob。次に、lineを結果の値に設定します(またはその値が配列にない場合、bashはnull / nullを返します)。

関連情報