私のディレクトリには、.idat
またはで終わるファイルのペアのリストが含まれています。_Grn
_Red
各ペアに対して、最初の区切り文字の前にサブストリングで名前付きディレクトリを作成し、ファイルを_
そのディレクトリに移動しようとします。
ディレクトリが存在しない場合は、ファイルを移動する前にディレクトリを作成してください。
私のコード:
for file in *.idat;
do directory_name=${file%_*} \
mkdir directory_name \
if ${file%_*}==directory_name;
then
mv $file directory_name;
fi;
done
逆追跡:
-bash: syntax error near unexpected token `then'
ファイル名:
00f3408c-5ad1-4afb-9eac-3392aa92e42c_noid_Grn.idat
00f3408c-5ad1-4afb-9eac-3392aa92e42c_noid_Red.idat
0317b249-9256-47fe-9533-3ca91c07e3fd_noid_Grn.idat
0317b249-9256-47fe-9533-3ca91c07e3fd_noid_Red.idat
039f8688-b4cd-4931-a8f5-40bcb1fbd8f0_noid_Grn.idat
039f8688-b4cd-4931-a8f5-40bcb1fbd8f0_noid_Red.idat
予想フォルダ名:
00f3408c-5ad1-4afb-9eac-3392aa92e42c
0317b249-9256-47fe-9533-3ca91c07e3fd
039f8688-b4cd-4931-a8f5-40bcb1fbd8f0
答え1
次のようにする必要があります。
shopt -s nullglob extglob # dotglob
for file in [^_]*_@(Grn|Red).idat; do
dirname=${file%%_*}
mkdir -p -- "$dirname" &&
mv -- "$file" "$dirname"
done
dotglob
(隠しアイテムも考慮するにはコメントを外してください。)
\
行の終わりは行連続。読みやすくするために長い行を壊すために使用されます。
do directory_name=${file%_*} \
mkdir directory_name \
if ${file%_*}==directory_name
同じですか?
do directory_name=${file%_*} mkdir directory_name if ${file%_*}==directory_name
したがって、名前付きディレクトリをmkdir
作成し、その環境に渡すように要求します。directory_name
if
00f3408c-5ad1-4afb-9eac-3392aa92e42c_noid==directory_name
directory_name=00f3408c-5ad1-4afb-9eac-3392aa92e42c_noid
その後、シェルはthen
対応するif
。
でパターンマッチングを実行するには、コンストラクタまたは演算子をbash
使用できますが、ここでは必須ではありません。case
[[ text = pattern ]]
--
また、リストコンテキストの拡張はbashで引用し、ほとんどのコマンドではオプションではない引数をオプションから分離する必要があります。
${var%pattern}
削除最短末尾のパターンと一致する文字列です$var
。${var%%pattern}
最初の文字列のすべての文字列を削除するには、最も長い文字列を削除する必要があります_
。[^_]*...
ファイルがaで始まらないようにするには、as globパターンを使用していることがわかります。_
これにより、空のディレクトリ名が生成されます。
Grn
ファイルごとに常に1つのファイルがあることがわかっている場合は、次のようにして合計呼び出し数を半分に減らすことができますRed
。mkdir
mv
shopt -s nullglob # dotglob
for file in [^_]*_Red.idat; do
dirname=${file%%_*}
mkdir -p -- "$dirname" &&
mv -- "$file" "${file%_*}_Grn.idat" "$dirname"
done