我正在尝试从终端命令行执行以下操作:
将目录每个子文件夹中的文本文件(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