多くのファイルを含む複数のフォルダがあり、各フォルダには同じ名前の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
)が必要です。