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
オプションはインラインスクリプトに設定されており、構築されたパターンがない何かに一致する場合、パターンは削除されます (展開されずに保持されるのではなく)。
例には、示されているファイル名のいずれにも一致しない文字列があるため、パターンが一致するかどうかを明示的にテストしています。これは、位置パラメータのリストを glob 展開の結果に設定し、リストの長さ ( $#
) が 0 より大きいかどうかをテストすることによって行われます。
明らかに、次のようにしなくてもこれを行うことができます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
これは、プレフィックス文字列にもファイル名にも埋め込まれた改行が含まれていないことを前提としています。
答え2
考えられる解決策は次のとおりです:
cat strings.txt | xargs -I '%' find . -type f -name "%*" -exec mv -t your_path {} +
移動したGCA_000007405.1_ASM740v1_protein.faa
のは、唯一の一致です。
答え3
複雑なものは必要ありませんxargs
。すべてのファイルが同じディレクトリにある場合は、次の操作を行うだけで十分です。
$ while read string; do
mv "$string"_* ./Data;
done < strings.txt
または、名前が a で始まる場合-
や、他の奇妙な文字が含まれている可能性がある場合は、次のようにします。
$ while read -r string; do
mv -- "$string"_* ./Data;
done < strings.txt
答え4
素早く汚いハック:cat strings.txt| xargs -i sh -c 'mv {}* your/path/'>&/dev/null
より少ない、より正確なハック:export dir=$(ls -1); cat strings.txt| xargs -i sh -c 'grep "^{}" <<<$dir && mv {}* your/path'; dir=""