将目录 txt 文件转换为具有适当列名称的有用的合并 csv 文件

将目录 txt 文件转换为具有适当列名称的有用的合并 csv 文件

我正在尝试从终端命令行执行以下操作:

将目录每个子文件夹中的文本文件(allMovement_Regressors.txt;12 列;548 行)转换为存储在同一子文件夹中的 csv 文件。尝试了这段代码,但只给了我一个将每个数据集堆叠在一起的文件:

cat */*/*/*/allMovement_Regressors.txt | tr -s '[:blank:]' ',' > ofile.csv

目录结构:

/Volumes/My\ Book\ Studio/Directory/1/Results/allMovement_Regressors.txt
/Volumes/My\ Book\ Studio/Directory/2/Results/allMovement_Regressors.txt
/Volumes/My\ Book\ Studio/Directory/3/Results/allMovement_Regressors.txt

将每个子文件夹中的所有 csv 文件连接到一个 csv 文件中,其中增量数据连接到前一个数据集的右侧,列根据子文件夹名称和变量顺序命名,如下所示:

1_1 1_2 1_3 1_4 1_5 1_6 1_7 1_8 1_9 1_10 1_11 1_12 2_1 2_2 2_3 2_4 2_5 2_6 2_7 2_8 2_9 2_10 2_11 2_12 3_1 3_2 3_3 3_4 3_5 3_6 3_7 3_8 3_9 3_10 3_11 3_12 

非常感谢。

答案1

要创建单独的 csv 文件:

$ find /Volumes/My\ Book\ Studio/ -type f -name 'allMovement_Regressors.txt' \
-exec bash -c 'tr -s "[:blank:]" "," < "$1" > "${1%.txt}.csv"' tocsv {} \;

“tocsv”将作为 exec 中 bash 脚本的名称显示在您的进程列表中。

如果您知道包含“allMovement_Regressors.txt”的目录数量,则可以像这样编写标题行(将 X 替换为正确的数字):

printf '%s,' {1..X}_{1..12} | sed 's/,$/\n/' > ofile.csv

并将它们放在一起:

$ find /Volumes/My\ Book\ Studio/ -type f -name 'allMovement_Regressors.csv' -print0 \
| sort -z \
| xargs -0 paste \
| tr '\t' ',' >> ofile.csv

请注意,文件在paste组合在一起之前将按数字排序。我在这里使用是-print0因为你的文件名中有空格。 paste将使用您在 csv 中不需要的制表符分隔列,因此我们也需要替换它。

更新

@bu5hman 回答了如何创建标题。我完全是在偷这个!如果您喜欢我的答案,请务必投票@bu5hman 的答案:-)

合并我们的答案,编写一个thingy.sh您可以提供给的脚本-exec

#!/bin/bash
t=$(echo "$1" | grep -Po "(?<=/)[0-9]+(?=/)")
u=$(echo 1_$(seq -s " ${t}_" $(cat "$1" | awk "{print NF}")))

sed "i \\$u" "$1" \
| tr -s "[:blank:]" "," > "${1%.txt}.csv"

然后将其输入-exec

find Volumes/My\ Book\ Studio/ -type f -name 'allMovement_Regressors.txt' \
-exec /path/to/thingy.sh {} \;

然后用我的第二个find命令将所有内容放在一起。

答案2

由于文件的聚合在上面已经得到了很好的回答,那么下面如何在聚合之前将标头注入到每个文件中。使用只有数字的目录作为标签,并允许任意数量的字段。

从 sed 中删除-i以测试......

find ./tmp -type f -name "qwerty" -exec sh -c 't=$(echo "$1" | grep -Po "(?<=/)[0-9]+(?=/)"); u=$(echo ${t}_$(seq -s " ${t}_" $(cat "$1" | awk "{print NF}"))); sed -i "i \\$u" "$1"' sh {} \;

文件位于/home/bu5hman/tmp/1/end/qwerty

内容

q w e r t y u i o p

输出

1_1 1_2 1_3 1_4 1_5 1_6 1_7 1_8 1_9 1_10
q w e r t y u i o p

当然,可以将输出重定向到一组临时文件以保留原始文件。

答案3

你想要paste而不是cat

paste -d' ' */*/*/*/allMovement_Regressors.txt | tr -s '[:blank:]' ',' > ofile.csv

相关内容