同じプレフィックスとサフィックスを持つファイルを同じディレクトリに移動するためのアルゴリズム設計と C コードの実装

同じプレフィックスとサフィックスを持つファイルを同じディレクトリに移動するためのアルゴリズム設計と C コードの実装

1. 要件の説明

Linux システムの複数のディレクトリに、同じプレフィックスとサフィックスを持つファイルがいくつかあります。それらを同じディレクトリに移動するプログラムを作成してください。

たとえば、FileDir1、FileDir2、FileDir3 という 3 つのソース ディレクトリがあり、それぞれに File_1.txt、File_2.txt、File_3.txt というファイルが含まれています。これら 3 つのファイルはプレフィックス (File_) とサフィックス (txt) が同じなので、同じ結果ディレクトリ (GatherDir であると仮定) に移動されます。

2. アルゴリズム設計

要件に基づいて、図 1 に示すプログラム フローを採​​用できます。

図1 全体的なプロセスフロー

3. 特別なプロセスに関する考慮事項

プログラムを作成する過程では、次のような特別なプロセスが考慮されます。

1. ディレクトリのスキャン中にエラーが発生した場合、プログラムは次のディレクトリをスキャンせずに停止します。

2. 空のファイル(つまり、ファイル サイズが 0)がある場合は、結果ディレクトリに移動せずに、ソース ディレクトリで直接削除します。

3. ソース ディレクトリに配置されたファイルをいつでも処理できるように、プログラムはソース ディレクトリを一定の間隔 (1 分など) でスキャンします。つまり、人間による操作がなければ、プログラムは起動後継続的に実行されます。

4. プログラムコード

  1. /******************************************************************************************
  2. * 著作権 (C) 2016、Zhou Zhaoxiong。
  3. *
  4. * ファイル名: FileGather.c
  5. * ファイルID: なし
  6. * コンテンツの概要: さまざまなディレクトリにある同じプレフィックスを持つファイルを 1 つのディレクトリに集めます
  7. * その他の指示: なし
  8. * 現在のバージョン: V1.0
  9. * 著者: 周昭雄
  10. * 完成日: 20160513
  11. *
  12. ******************************************************************************/
  13. #include <stdio.h>
  14. #include <文字列.h>
  15. #include <dirent.h>
  16. #include <ftw.h>
  17. #include <時間.h>
  18.  
  19. // データ型を再定義する
  20. typedef 符号付きint INT32;
  21. typedef 符号なしint UINT32;
  22. typedef unsigned char UINT8;
  23.  
  24. //グローバル変数の定義
  25. UINT8 g_szGatherDir[256] = {0}; // サマリーファイルのディレクトリ
  26. UINT8 g_szFilePrefix[20] = {0}; // 要約するファイルのプレフィックス
  27. UINT8 g_szFileSuffix[20] = {0}; // 要約するファイルのサフィックス
  28.  
  29.  
  30. // マクロ定義
  31. #define DIRNUM 3 // スキャンするディレクトリの数
  32.  
  33. // 関数宣言
  34. INT32 SelectFlies(構造体 dirent *pDir);
  35. void スキャンディレクトリと収集(void);
  36. void スリープ(UINT32 iCountMs);
  37.  
  38.  
  39. /****************************************************************
  40. * 機能説明: 主な機能
  41. * 入力パラメータ: なし
  42. * 出力パラメータ: なし
  43. * 戻り値: 0 - 実行完了
  44. * その他の指示: なし
  45. * 変更日 バージョン番号 修正者 変更内容
  46. * -------------------------------------------------------------  
  47. * 20160513 V1.0 作成者: Zhou Zhaoxiong
  48. ************************************************************************/
  49. INT32メイン(void)
  50. {
  51. // サマリーファイルのディレクトリを取得する
  52. snprintf(g_szGatherDir, sizeof(g_szGatherDir)-1, "%s/zhouzx/TestDir/GatherDir" , getenv( "HOME" ));
  53.  
  54. // 要約するファイルのプレフィックスを取得します
  55. snprintf(g_szFilePrefix, sizeof(g_szFilePrefix)-1, "File_" );
  56.  
  57. // 要約するファイルのサフィックスを取得します
  58. snprintf(g_szFileSuffix, sizeof(g_szFileSuffix)-1, ".txt" );
  59.  
  60. // 呼び出し関数実行ファイルの概要
  61. (1)
  62. {
  63. スキャンディレクトリと収集();
  64.  
  65. Sleep(60 * 1000); // 1分ごとにファイルサマリーを実行する
  66. }
  67.  
  68. 0を返します
  69. }
  70.  
  71.  
  72. /******************************************************************************************
  73. * 機能の説明: プレフィックスとサフィックスに基づいてファイルを選択する
  74. * 入力パラメータ: dir-ディレクトリ
  75. * 出力パラメータ: なし
  76. * 戻り値: 0-失敗、1-成功
  77. * その他の指示: なし
  78. * 変更日 バージョン番号 修正者 変更内容
  79. * --------------------------------------------------------------------  
  80. * 20160513 V1.0 作成者: ZhouZhaoxiong
  81. ******************************************************************************/
  82. INT32 SelectFlies(構造体 dirent *pDir)
  83. {
  84. INT32 iPrefixLen = 0;
  85. INT32 iループフラグ = 0;
  86. INT32 iSelectResult = 0;
  87.  
  88. (pDir == NULL )の場合
  89. {
  90. printf( "SelectFlies:入力パラメータがNULLです!\n" );
  91. 0を返します
  92. }
  93.  
  94. // ファイルのプレフィックスとサフィックスを一致させる
  95. iPrefixLen = strlen(g_szFilePrefix); // プレフィックスはg_szFilePrefixです
  96. iSelectResult = ((0 == strncmp(pDir->d_name, g_szFilePrefix, iPrefixLen))
  97. && ((strncmp(&pDir->d_name[strlen(pDir->d_name) - strlen(g_szFileSuffix)], g_szFileSuffix, strlen(g_szFileSuffix)) == 0)));
  98.  
  99. if (iSelectResult == 1) // プレフィックスに一致するファイルが見つかりました
  100. {
  101. 1 を返します
  102. }
  103. それ以外 
  104. {
  105. 0を返します
  106. }
  107. }
  108.  
  109.  
  110. /******************************************************************************************
  111. * 機能の説明: ディレクトリをスキャンし、同じプレフィックスを持つファイルを要約します
  112. * 入力パラメータ: なし
  113. * 出力パラメータ: なし
  114. * 戻り値: なし
  115. * その他の指示: なし
  116. * 変更日 バージョン番号 修正者 変更内容
  117. * --------------------------------------------------------------------  
  118. * 20160513 V1.0 作成者: ZhouZhaoxiong
  119. ******************************************************************************/
  120. void スキャンディレクトリと収集(void)
  121. {
  122. INT32 iScanDirRet = 0;
  123. UINT32 iDirIdx = 0;
  124. UINT32 iFileIdx = 0;
  125. UINT32 iFileCount = 0;
  126. UINT32 iScanedNoFileDirCount = 0;
  127. UINT32 iFileSize = 0;
  128. INT32 iRetVal = 0;
  129. UINT8 szFileDir[256] = {0};
  130. UINT8 szScanedFile[512] = {0};
  131. UINT8 szCmdBuf[256] = {0};
  132. ファイル *fp = NULL ;
  133. 構造体 dirent **ppDirEnt = NULL ;
  134.  
  135. // 各ディレクトリを順番にスキャンしてファイルを要約します
  136. (iDirIdx = 1; iDirIdx <= DIRNUM; iDirIdx ++)の場合
  137. {
  138. memset(szFileDir, 0x00, sizeof(szFileDir));
  139. snprintf(szFileDir, sizeof(szFileDir)-1, "%s/zhouzx/TestDir/FileDir%d" 、getenv( "HOME" 、iDirIdx);
  140.  
  141. iScanDirRet = scandir(szFileDir, &ppDirEnt, SelectFlies, alphasort);
  142. if (iScanDirRet < 0) // ディレクトリのスキャン中にエラーが発生しました
  143. {
  144. printf( "ScanDirAndGather:exec scandir が失敗しました。パス=%s\n" , szFileDir);
  145. 戻る;
  146. }
  147. else if (iScanDirRet == 0) // ディレクトリにファイルがありません
  148. {
  149. printf( "ScanDirAndGather:ディレクトリ%sに条件に合うファイルがありません\n" , szFileDir);
  150.  
  151. スキャンされたファイルディレクトリ数++;
  152. if (iScanedNoFileDirCount >= DIRNUM) // すべてのディレクトリに条件を満たすファイルが存在しないことを示します
  153. {
  154. printf( "ScanDirAndGather: %d 個のディレクトリすべてで条件に合うファイルがスキャンされませんでした\n" , iScanedNoFileDirCount);
  155. 戻る;
  156. }
  157. }
  158. else // 条件を満たすファイルをサマリーディレクトリに移動する
  159. {
  160. (iFileIdx = 0; iFileIdx < iScanDirRet; iFileIdx ++)の場合
  161. {
  162. // まずスキャンしたファイルが空ファイルかどうかを判断し、空ファイルの場合は直接削除し、空ファイルでない場合は移動操作を実行します
  163. memset(szScanedFile, 0x00, sizeof(szScanedFile));
  164. snprintf(szScanedFile, sizeof(szScanedFile) - 1, "%s/%s" , szFileDir, ppDirEnt[iFileIdx]->d_name);
  165. fp = fopen(szScanedFile, "r" );
  166. if (fp == NULL ) // ファイルを開けなかった場合は直接戻ります
  167. {
  168. printf( "ScanDirAndGather:ファイル%sのオープンに失敗しました。確認してください!\n" , szScanedFile);
  169. 戻る;
  170. }
  171. fseek(fp, 0, SEEK_END);
  172. ファイルサイズ = ftell(fp);
  173. if (iFileSize == 0) // ファイルは空のファイルです
  174. {
  175. printf( "ScanDirAndGather:%s は空のファイルなので、直接削除してください!\n" , szScanedFile);
  176. memset(szCmdBuf, 0x00, sizeof(szCmdBuf));
  177. snprintf(szCmdBuf, sizeof(szCmdBuf) - 1, "rm %s" , szScanedFile);
  178. システム(szCmdBuf);
  179. }
  180. それ以外 
  181. {
  182. memset(szCmdBuf, 0x00, sizeof(szCmdBuf));
  183. snprintf(szCmdBuf, sizeof(szCmdBuf) - 1, "mv %s %s" , szScanedFile, g_szGatherDir);
  184. システム(szCmdBuf);
  185.  
  186. printf( "ScanDirAndGather:now, %s\n" , szCmdBuf);
  187.  
  188. ファイルカウント++;
  189. }
  190. }
  191. }
  192. }
  193.  
  194. printf( "ScanDirAndGather: 今回は合計 %d 個のファイルを %s に移動しました\n" , iFileCount, g_szGatherDir);
  195.  
  196. 戻る;
  197. }
  198.  
  199.  
  200. /******************************************************************************************
  201. * 機能説明: プログラム休止状態
  202. * 入力パラメータ: iCountMs - スリープ時間 (単位: ms)
  203. * 出力パラメータ: なし
  204. * 戻り値: なし
  205. * その他の指示: なし
  206. * 変更日 バージョン番号 修正者 変更内容
  207. * ------------------------------------------------------------------  
  208. * 20160513 V1.0 作成者: Zhou Zhaoxiong
  209. ****************************************************************************/
  210. void スリープ(UINT32 iCountMs)
  211. {
  212. 構造体timeval t_timeout = {0};
  213.  
  214. (iCountMs < 1000)の場合
  215. {
  216. t_timeout.tv_sec = 0;
  217. t_timeout.tv_usec = iCountMs * 1000;
  218. }
  219. それ以外 
  220. {
  221. t_timeout.tv_sec = iCountMs / 1000;
  222. t_timeout.tv_usec = (iCountMs % 1000) * 1000;
  223. }
  224. select (0, NULL , NULL , NULL , &t_timeout); // select関数を呼び出してプログラムをブロックする
  225. }

5. プログラムのテスト

記述したプログラム「FileGather.c」を Linux マシンにアップロードし、「gcc -g -o FileGather FileGather.c」コマンドを使用してプログラムをコンパイルし、「FileGather」ファイルを生成します。以下はプログラムの詳細なテストです。

1. プログラムを起動する前に、File_1.txt、File_2.txt、File_3.txt の各ファイルをそれぞれソース ディレクトリ FileDir1、FileDir2、FileDir3 に配置します。プログラムは次のように実行されます。

  1. ScanDirAndGather:今、mv /home/zhou/zhouzx/TestDir/FileDir1/File_1.txt /home/zhou/zhouzx/TestDir/GatherDir  
  2. ScanDirAndGather:今、mv /home/zhou/zhouzx/TestDir/FileDir2/File_2.txt /home/zhou/zhouzx/TestDir/GatherDir  
  3. ScanDirAndGather:今、mv /home/zhou/zhouzx/TestDir/FileDir3/File_3.txt /home/zhou/zhouzx/TestDir/GatherDir  
  4. ScanDirAndGather:今回は合計3つのファイル/home/zhou/zhouzx/TestDir/GatherDir移動しました

ご覧のとおり、ソース ディレクトリ内の 3 つのファイルは存在しなくなりました。これらは結果ディレクトリ GatherDir に移動されました。

  1. ~/zhouzx/TestDir/GatherDir>ll  
  2. -rw——- 1 zhou users 12 2016-05-13 15:14 File_1.txt  
  3. -rw——- 1 zhou users 12 2016-05-13 15:14 File_2.txt
  4. -rw——- 1 周 ユーザー 12 2016-05-13 15:14 File_3.txt

2. しばらくしてから、ファイル File1_4.txt をソース ディレクトリ FileDir1 に配置すると、プログラムは次のように実行されます。

  1. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir1条件に合うファイルがありませ 
  2. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir2条件に合うファイルがありませ 
  3. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir3条件に合うファイルがありませ 
  4. ScanDirAndGather: 条件合うファイルがスキャンされませでした 3ディレクター

ご覧のとおり、プレフィックスが一致しないため、File1_4.txt ファイルはソース ディレクトリ FileDir1 に残っています。

  1. ~/zhouzx/TestDir/FileDir1>ll  
  2. -rw——- 1 周 ユーザー 36 2016-05-13 15:19 File1_4.txt

3. しばらくしてから、File_5.txt ファイルをソース ディレクトリ FileDir2 に置き、File_11.c ファイルをソース ディレクトリ FileDir3 に置きます。プログラムは次のように実行されます。

  1. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir1条件に合うファイルがありませ 
  2. ScanDirAndGather:今、mv /home/zhou/zhouzx/TestDir/FileDir2/File_5.txt /home/zhou/zhouzx/TestDir/GatherDir  
  3. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir3条件に合うファイルがありませ 
  4. ScanDirAndGather:今回は合計 1 つのファイル/home/zhou/zhouzx/TestDir/GatherDir移動しました

ソース ディレクトリ FileDir2 内のファイル File_5.txt はサフィックスが一致しないため存在しなくなり、ソース ディレクトリ FileDir3 内のファイル File_11.c はまだ存在していることがわかります。

  1. ~/zhouzx/TestDir/FileDir3>ll  
  2. -rw——- 1 zhou users 4 2016-05-13 15:23 File_11.c

File_5.txt は結果ディレクトリ GatherDir に移動されました:

  1. ~/zhouzx/TestDir/GatherDir>ll  
  2. -rw——- 1 周 ユーザー 12 2016-05-13 15:14 File_1.txt  
  3. -rw——- 1 zhou users 12 2016-05-13 15:14 File_2.txt  
  4. -rw——- 1 周 ユーザー 12 2016-05-13 15:14 File_3.txt  
  5. -rw——- 1 周 ユーザー 36 2016-05-13 15:23 File_5.txt

4. しばらくすると、空のファイル File_7.txt がソース ディレクトリ FileDir2 に配置され、プログラムは次のように実行されます。

  1. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir1条件に合うファイルがありませ 
  2. ScanDirAndGather:/home/zhou/zhouzx/TestDir/FileDir2/File_7.txt は空のファイルので、直接削除してください  
  3. ScanDirAndGather:ディレクトリ /home/zhou/zhouzx/TestDir/FileDir3条件に合うファイルがありませ 
  4. ScanDirAndGather: 今回、合計 0 個のファイル/home/zhou/zhouzx/TestDir/GatherDir移動しました

ソース ディレクトリ FileDir2 内のファイル File_7.txt が削除されたことがわかります。

  1. ~/zhouzx/TestDir/FileDir2>ll  
  2. 合計 0

6. 需要拡大

この記事の要件と手順に基づいて、要件に対する次の拡張を検討できます。

1. ファイルを移動する前に、結果ディレクトリに同じファイル名のファイルが存在するかどうかを確認します。存在する場合は、ソースディレクトリからファイルを直接削除します。存在しない場合は、ファイルを結果ディレクトリに移動します。

2. 結果ディレクトリ内のファイルが多すぎるのを避けるために、プログラムにクリーンアップ メカニズムを追加して、一定期間以上保存されているファイルを削除することができます。

3. プログラムの柔軟性を反映するために、一部のファイル情報(ファイルのプレフィックス、サフィックス、保存ディレクトリ、スキャン間隔など)を設定ファイルに保存できます。プログラムが起動すると、関連する設定項目の値が読み取られ、後続のディレクトリスキャンとファイル移動操作が実行されます。

[この記事は51CTOコラムニストの周兆雄氏によるオリジナル記事です。著者のWeChat公開アカウント:周の論理(logiczhou)]

この著者の他の記事を読むにはここをクリックしてください

<<:  [文字列処理アルゴリズム] 最長共通部分文字列を取得するためのアルゴリズム設計とCコード実装

>>:  ソースディレクトリ内のファイルをプレフィックスに応じて異なるディレクトリに分散するためのアルゴリズム設計と C コードの実装

ブログ    
ブログ    
ブログ    

推薦する

AIチップブラックテクノロジーインベントリ

ビッグデータとディープラーニングの利用が増えるにつれて、基盤となるハードウェアとチップに新たな要件が...

新しい脳のようなコンピューティングデバイスは人間の学習をシミュレートできる:この論文はNature Communications誌に掲載された。

「シナプストランジスタ」は、脳の可塑性を模倣して、データの処理と保存を同時に行うことができます。 ...

SQL SERVER データマイニング: クラスタリングアルゴリズムとシーケンシャルクラスタリングアルゴリズムの理解

前回の「SQL SERVER データ マイニングと列の使用方法の理解」に続き、今回はSQL SERV...

神経系とビッグデータ、新しい次元削減アルゴリズムが脳をシンプルにする

ネイチャー・ニューロサイエンス誌に掲載されたレビュー記事で、カーネギーメロン大学のバイロン・M・ユー...

Google内部関係者、Bardチャットボットの有用性に疑問

10月12日、ブルームバーグは昨夜、グーグルとDiscordが共同で自社のAIチャットボット「Bar...

ディープラーニングは限界に達したのか?

[[255738]]ビッグデータダイジェスト制作編集者: Xiao Jiang、lvy、Wang ...

IoT/AIプロジェクトへの投資家を見つけるのに最適な方法

問題を解決するには、説明するのではなく検証する[[284237]]多くの IoT プロジェクトの提示...

人工知能、機械学習、ディープラーニング、データサイエンス

人工知能やデータサイエンスに不慣れな方であれば、これらの 4 つの用語を何度も目にしたことがあるはず...

人工知能が人々を失業させるのは悪いことではありません。それどころか、それは良い役割を果たします。

近年の科学技術の急速な発展に伴い、人工知能の概念が徐々に明確になってきています。特にOTT業界の重要...

ControlNet、「Split Everything」などの人気論文が受賞、ICCV 2023論文賞が発表

今週、フランスのパリで国際コンピュータビジョン会議 (ICCV) が開幕しました。 ICCVはコンピ...

年末総括: 2021 年の人工知能 (AI) と機械学習 (ML) の 5 つの主要な開発トレンド

[[359772]]来年、AI テクノロジーはビジネス業務にさらに深く浸透するでしょう。人工知能 (...

RPA製造業アプリケーション事例共有

5G が推進し主導する、デジタル技術変革の新世代が正式に到来しました。今日、インターネットの急速な変...

世界初の「自己複製」する生体ロボットが誕生。科学者たちの次なる目標とは?

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

...