ディレクトリ名を列名として使用して、同じ名前の単一列ファイルを貼り付けます。

ディレクトリ名を列名として使用して、同じ名前の単一列ファイルを貼り付けます。

同じ名前のテキストファイルがたくさんあります。各ファイルは異なるフォルダに保存され、各ファイルには次の数値列が含まれています。

FILE.TXT   FILE.TXT   FILE.TXT   FILE.TXT   ....

5            4              5            7
8            2              1            5
6            1              1            1
1            3              5            9
3            1              8            9
.           .                 .          .
.           .                 .          .
.           .                 .          .               

ファイルをスプレッドシート(​​CSV形式)にマージし、列の名前をファイルを含むフォルダと同じにしたいと思います。私は次のようにforループを試しました。

#!/bin/bash
  in=a/b/c
  for i in $(cat $in/folders_names.txt); do    # i is the folder name that contain the file.txt
  paste ${in}/${i}/file.txt         
   done > all_files.txt
   sed 's/  */,/g' all_files.txt >all_files.csv &

このコードは、すべてのファイルのすべての列を1つの列(all_files.txtファイル)に貼り付けます。何が間違っているのかわかりません。どんな提案がありますか?

ベストアンサー1

{ paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \\n | cut -c2-; \
sed 's|.*|'"${in}"'/&/file.txt|' "${in}"/folders_names.txt \
| tr \\n \\0 | xargs -0 paste -d,; } > all_files.csv

最初のコマンド

paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \\n | cut -c2-

たとえば、次のような場合はタイトルを印刷します"${in}"/folders_names.txt

w
x
y
z

それは印刷するw,x,y,z

このsedコマンドは、各行がパスになるように同じファイルを処理します。たとえば、次のようになりますin=a/b/c

a/b/c/w/file.txt
a/b/c/x/file.txt
a/b/c/y/file.txt
a/b/c/z/file.txt

結果は viatrへの null で区切られた入力に変換されるため、最終出力は次のようになります。pastexargs -0

w,x,y,z
5,4,5,7
8,2,1,5
6,1,1,1
1,3,5,9
3,1,8,9

埋め込まれた空白(通常のファイル名など)に行が含まれていない場合は、folders_names.txt次を実行できます。

{ paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \\n | cut -c2-; \
paste -d, $(sed 's|.*|'"${in}"'/&/file.txt|' "${in}"/folders_names.txt); } > all_files.csv

2番目のコマンドは次に拡張されるため

paste -d, a/b/c/w/file.txt a/b/c/x/file.txt a/b/c/y/file.txt a/b/c/z/file.txt

おすすめ記事