複数のサブフォルダにある同じ名前のファイルをマージする

複数のサブフォルダにある同じ名前のファイルをマージする

多くのファイルを含む複数のフォルダがあり、各フォルダには同じ名前のtxtファイルがあり、同じ名前のファイルを1つのtxtファイルにマージしたいと思います。

例:

folder/
     -sub1
     -sub2
     -sub3
      .
      .
      .
     -sub28

各サブフォルダには複数のファイルがあります。

EAF001.ID001.txt  EAF001.ID002.txt  EAF001.ID003.txt  EAF001.ID004.txt
EAF001.ID005.txt  EAF001.ID006.txt  EAF001.ID007.txt  EAF001.ID008.txt
EAF001.ID009.txt  EAF001.ID010.txt  EAF001.ID011.txt  EAF001.ID012.txt
EAF001.ID013.txt  EAF001.ID014.txt  EAF001.ID015.txt  EAF001.ID016.txt

同じ名前のファイルをマージしたいです。

EAF001.ID001.merge.txt  EAF001.ID002.merge.txt  EAF001.ID003.merge.txt  EAF001.ID004.merge.txt
EAF001.ID005.merge.txt  EAF001.ID006.merge.txt  EAF001.ID007.merge.txt  EAF001.ID008.merge.txt
EAF001.ID009.merge.txt  EAF001.ID010.merge.txt  EAF001.ID011.merge.txt  EAF001.ID012.merge.txt
EAF001.ID013.merge.txt  EAF001.ID014.merge.txt  EAF001.ID015.merge.txt  EAF001.ID016.merge.txt

どんな助けでも大変感謝します。

ベストアンサー1

export dir='/path/to/folder'

find "$dir" -mindepth 2 -type f -name 'EAF*.txt' \
  -exec sh -c 'for f; do
                 bn=$(basename "$f" .txt);
                 cat "$f" >> "$dir/$bn.merged.txt";
               done' sh {} +

この-mindepth 2オプションは、/path/to/folder ディレクトリ自体のファイルを処理から除外します (つまり、サブディレクトリ内のファイルのみを検索する)、出力ファイルが既に存在する場合、出力ファイルはそれ自体に関連付けられません。

重複したファイル名があるかどうかに関係なく、「merged.txt」出力ファイルにファイルが追加されます。

重複したファイル名のみをマージしたい場合:

typeset -Ax counts # declare $counts to be an exported associative array
export dir='/path/to/folder'

# find out how many there are of each filename
while read -d '' -r f; do
  let counts[$f]++;
done < <(find "$dir" -mindepth 2 -type f -name 'EAF*.txt' -print0)

# concatenate only the duplicates
find "$dir" -mindepth 2 -type f -name 'EAF*.txt' \
  -exec bash -c 'for f; do
                   if [ "${counts[$f]}" -gt 1 ]; then
                     bn=$(basename "$f" .txt);
                     cat "$f" >> "$dir/$bn.merged.txt";
                   fi
                 done' sh {} +

これには、bash連想配列をサポートする他のシェル(POSIXなどsh)が必要です。

おすすめ記事