连接子目录中同名的 csv 文件

连接子目录中同名的 csv 文件

我发现一些脚本将来自不同子目录的文本文件连接起来,但它们都生成了像“output.txt”这样的输出文件,但没有保留原始文件名。

结构

Folder_A
   a.csv
   b.csv
   ...

Folder_B
   a.csv
   b.csv
   ...

我想要收到一个新的 a.csv,它合并了 Folder_A 中的 a.csv 和 Folder_B 中的 a.csv 等等,然后写入父目录或新的输出目录。

在我的例子中,子目录中的文件数量是相似的。 可能会有两个以上的子目录。

生成的 csv 文件应该只包含一个标题行。

我知道我必须循环遍历目录,但我不知道如何创建文件名列表并搜索它们,以及如何嵌套所有这些。

任何帮助都非常感谢。

答案1

您可以尝试这个 bash 脚本。它在第一个目录中找到名为“.csv”的文件,并在删除(1d)其第一行(csv 标题)后将其与在第二个目录中找到的相同文件名连接起来。生成的文件位于第三个目录中。

a=Folder_A
b=Folder_B
c=Folder_C
mkdir -p $c
(cd $a && find . -type f -name '*.csv') |
while read file
do    ( cat "$a/$file"
        [ -f "$b/$file" ] && sed '1d' <"$b/$file"
      ) >"$c/$file"
done

此 bash 脚本在作为参数给出的目录中查找名为“.csv”的文件,并在删除(1d)其第一行(csv 标头)后将它们与稍后找到的任何同名文件连接起来。生成的文件位于 Folder_concat 目录中。

#!/bin/bash
dest=Folder_concat
mkdir -p $dest
find "$@" -name "$dest" -prune -o -name '*.csv' |
while read file
do    base=$(basename "$file")
      if [ -s "$dest/$base" ]
      then sed '1d' <"$file"
      else cat "$file"
      fi >>"$dest/$base"
done

答案2

如果你做得更像 Unix,更像 shell,那就更容易了——只需要 2 个命令:

  1. 获取文件名列表(=所有目录文件的不同联合)
  2. 将所有目录的部分文件放入输出目录的整个文件中

#### get list of files as Distinct Union of all dirs' files # (alas, basename can only handle ONE filename at a time # so have to loop through them)

DISTINCTUNION_ALLFILES=`
  for FILE in Folder_{A,B,C,D}/*
  do
    basename $FILE
  done  | sort  | uniq

  `
# 
# syntax explanation:
#  1. for VARIABLE in LIST: loops b/w DO and DONE, with Variable taking each value in the list
#  2. {A,B,C} is Shell (bash) expansion: creates N words, 1 for each comma-separated sub-word
#           e.g.: dir{A,B}            -> dirA  dirB     
#           e.g.: myfile.{dll,o,out}  -> myfile.dll  myfile.o  myfile.out
#           e.g.: myfile{,.tmp}       -> myfile  myfile.tmp
#  3. BASENAME strips away the Path leaving just the filename (cf.Dirname for the opposite)
#  4. the BACKQUOTES (``) take the command's Output and re-place it on that part of the commandline
#  5. | takes the total output and Sorts it, then | takes _that_ to Uniq which removes duplicates
#  6. the whole lot is then stored in the VariableName



#### cat all dirs' part-file(s) into Output dir's whole-file(s)

for FILE in $DISTINCTUNION_ALLFILES
do
    cat Folder_{A,B,C,D}/$FILE  > OutputDir/$FILE
done
#
# syntax explanation:
# 1. same For loop as before, same filename expansion as before
# 2. files which are not in ALL dirs will generate errors but won't stop the conCATenation
# 3. result goes into OutputDir, 1 file per filename

相关内容