strings.txt
文字列のリストを含むファイルがあります。
GCA_001677475.1
GCA_003410275.1
GCA_002310615.1
GCA_000007405.1
GCA_000219515.3
私のディレクトリには、次の名前のファイルがたくさんあります。
GCA_000005845.2_ASM584v2_protein.faa
GCA_000006925.2_ASM692v2_protein.faa
GCA_000007405.1_ASM740v1_protein.faa
GCA_000007445.1_ASM744v1_protein.faa
GCA_000008865.2_ASM886v2_protein.faa
GCA_000009565.2_ASM956v1_protein.faa
その名前をに移すだけです。これまで、次のようにstrings.txt
使ってみました。xargs
mv
cat strings.txt | xargs -I % mv %*faa ./Data
しかし、それを正規表現として扱うmv
ことなく、%*faa
正確な名前のファイルを見つけようとします(もちろん何も見つかりません)。私も試してみましたが、ls
同じように動作します。
cat strings.txt | xargs -I {} ls {}*faa
ではどうすればいいですか?
ベストアンサー1
xargs bash -O nullglob -c '
for prefix do
set -- "$prefix"*.faa
[ "$#" -gt 0 ] && mv -- "$@" ./Data
done' sh <strings.txt
これは、インラインスクリプトにxargs
一括して文字列を供給するために使用されます。strings.txt
bash
各文字列について、インラインスクリプトは現在のディレクトリにそのbash
文字列(パターンを作成するために最後に追加されたもの)と一致するファイル名があるかどうかをテストし、その場合はそのファイルがすでに存在すると仮定してそのディレクトリに移動します。*.faa
Data
インラインスクリプトのシェルオプションを設定して構成されたnullglob
パターンいいえ何でも一致すると、パターンは削除されます(拡張されていないままではありません)。
あなたの例の一部の文字列があなたが表示したファイル名と一致しないため、パターン一致を明示的にテストしています。これは、位置引数リストをグローバル拡張結果に設定し、リストの長さ()がゼロより大きいかどうかをテストすることによって$#
行われます。
明らかに、次のように代わりにこれを行うこともできますxargs
。
shopt -s nullglob
while IFS= read -r prefix; do
set -- "$prefix"*.faa
[ "$#" -gt 0 ] && mv -- "$@" ./Data
done <strings.txt
これはまだ失敗するプレフィックス文字列の1つが何千ものファイル名と一致する場合(mv
コマンドラインが長すぎます)。この場合、以下を使用できます。
shopt -s nullglob
while IFS= read -r prefix; do
set -- "$prefix"*.faa
if [ "$#" -gt 0 ]; then
printf '%s\n' "$@" | xargs sh -c 'mv -- "$@" ./Data' sh
fi
done <strings.txt
これは、プレフィックス文字列またはファイル名に改行文字が含まれていないと仮定します。