多くのファイルを含む複数のフォルダがあり、各フォルダには同じ名前の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
)が必要です。
答え2
find
txtファイルを繰り返して、重複した名前を使用して計算できますwc
。重複する名前の数が1より大きい場合は、merge.txtファイルに追加されます。
#!/bin/bash
output_dir="output"
rm -rf "$output_dir"
mkdir "$output_dir"
for file in */*.txt; do
file_name=$(basename "$file" .txt)
duplicate_names_count=$(find . -type f -name "$file_name.txt" | wc -l)
if [ "$duplicate_names_count" -gt 1 ]; then
cat "$file" >> "$output_dir/${file_name}.merge.txt"
fi
done