名前でファイルをグループ化し、awk を使用して各ディレクトリに移動します。

名前でファイルをグループ化し、awk を使用して各ディレクトリに移動します。

私は名前(_の前の最初の数文字)に基づいてファイルをグループ化し、awkを使用してファイルを別のディレクトリに移動しようとしています(存在しない場合は新しいディレクトリを作成します)。

テストデータは、次のコマンドを使用して生成できます。

echo "1" > 123_20190911_110011.txt
echo "2" > 123_20190911_110012.txt
echo "0" > 123_20190910_110010.txt
echo "1" > 1234_20190911_110011.txt
echo "2" > 1234_20190911_110012.txt
echo "0" > 1234_20190910_110010.txt

ls -ltrの出力は次のとおりです。

-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190911_110011.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190911_110012.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190910_110010.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190911_110011.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190911_110012.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190910_110010.txt

この場合、2つのディレクトリ123と1234とファイルが次のディレクトリに移動すると予想します。

Dir 123 has files
 123_20190911_110011.txt
 123_20190911_110012.txt
 123_20190910_110010.txt
Dir 1234 has files
 1234_20190911_110011.txt
 1234_20190911_110012.txt
 1234_20190910_110010.txt

以下のコードは機能しません。ディレクトリは作成されず、エラーも表示されません。

for i in `ls -p | grep -v /` ## to list only files
do 
echo $i | awk -F'_' '{mkdir -p $1; cp $i $1}'
done

次のコマンドを使用してディレクトリを作成できますが、移動コマンドをどのように追加しますか?

for i in `ls -p | grep -v / `; do echo $i | awk -F'_' '{print $1; dir= $1}' | xargs mkdir -p ; done

答え1

内部でやってはいけませんmv。以下はうまくいきます:cpawk

for i in * ; do
  [ -f "$i" ] || continue
  dir_name="$(echo $i | awk -F'_' '{print $1}')"
  mkdir -p -- "$dir_name"
  cp -- "$i" "$dir_name"
done

awkただし、%bashで演算子を使用すると、最初の下線の後のすべてのエントリを削除して、代わりにディレクトリ名を取得できます。

for i in * ; do
  [ -f "$i" ] || continue
  dir_name="${i%%_*}"
  mkdir -p -- "$dir_name"
  cp -- "$i" "$dir_name"
done

(移動をご希望の場合はmv代わりにご利用ください)cp

答え2

すべてのファイル名をサンプルファイルに入れ、以下の手順に従ってください。

#step1 it creates directory

awk -F "_" '{print $1}' samplefile | awk '{if (!seen [$1]++)print "mkdir" " " $0}'| sh

#step2: moves file to respective directory

 for i in `awk -F "_" '{print $1}' samplefile | sort -u` ; do sed -n '/^'$i'_/p' samplefile | awk -v i="$i" '{print "mv" " " $1 " " i}'|sh ; done

関連情報