権限のないパスを変数に入れようとします。

権限のないパスを変数に入れようとします。

ディレクトリに興味のあるファイルが20個あります。 5つのグループに分けられ、各グループはファイル名に626から630の数字で識別されます。例えば(仮説的に) the-quick-brown-fox-jumps-over-627-lazy-dogs_1_bbduk.fq

各グループを繰り返し、ファイルパスをテキスト変数として一時的に保存したい(ループの他のコマンドと一緒に使用for)。これが私が今持っているものです:

for i in {626..630};do
  fw1=$(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)
  fw2=$(/scratch/[username]/data/*"$i"_*_1_bbduk.fq)
  rv1=$(/scratch/[username]/data/*"$i"-*_2_bbduk.fq)
  rv2=$(/scratch/[username]/data/*"$i"_*_2_bbduk.fq)
done

問題:正しいパスを取得しましたが(パスごとに1つのオプションのみ)、「権限が拒否されました」と表示され、後で変数をテキストとして使用できないようです。 bashがそれを実行しようとしているようですが、これは私が望むものではありません。

私は周りに一重引用符を追加してみました(例:fw1='$(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)'ワイルドカードが削除されました。二重引用符( "")を考えましたが、 "$i"変数をめちゃくちゃにせずにそれを使用する方法がわかりません。たとえば、試してみましたが、echoまだfw1=echo $(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)"権限拒否」の問題があります。

答え1

Bashは各ファイルを次のようにラップするため、ファイル名を指定しようとします。

$( ... )

これが望ましくない場合は、次を使用してください。

for i in {626..630}; do
  fw1=/scratch/[username]/data/*"$i"-*_1_bbduk.fq
  fw2=/scratch/[username]/data/*"$i"_*_1_bbduk.fq
  rv1=/scratch/[username]/data/*"$i"-*_2_bbduk.fq
  rv2=/scratch/[username]/data/*"$i"_*_2_bbduk.fq
done

編集する:

あなたのコメントによると、次のコードはあなたが望むものかもしれません。

for i in {626..630}; do
  fw1="$(compgen -G /scratch/[username]/data/*"$i"-*_1_bbduk.fq)"
  fw2="$(compgen -G /scratch/[username]/data/*"$i"_*_1_bbduk.fq)"
  rv1="$(compgen -G /scratch/[username]/data/*"$i"-*_2_bbduk.fq)"
  rv2="$(compgen -G /scratch/[username]/data/*"$i"_*_2_bbduk.fq)"
done

答え2

Jimは正確に識別します。コードに問題がありますが(IMO)、より良いソリューションはすでに持っているソリューションに近いです。

fw1=(/スクラッチ/ユーザー名/data/*"$i"-*_1_bbduk.fq)

(注:いいえ$) は glob と一致するファイル名の配列を提供します。少し厄介なことは、${#fw1[@]}配列に要素がいくつあるかを知らせることです。たとえば、数字がある場合は、およびを使用して4つの要素にアクセス  4できます ${fw1[0]}。ただし、プレーンはこれを提供するため、各パターンに一致するファイルがあると110%確信している場合は、短い形式を使用できます。${fw1[1]}${fw1[2]}${fw1[3]}$fw1${fw1[0]}

またはあなたは言うことができます

fw1=$(エコ/スクラッチ/ユーザー名/data/*"$i"-*_1_bbduk.fq)

繰り返しますが、あなたは近いです。 (ただし、パターンに一致する複数のファイルがある場合は、配列ソリューションがより優れています。)

関連情報