根据字段拆分文件并保存在使用根名称创建的子目录中

时间:2014-01-26 23:11:47

标签: linux awk split

我遇到了几段代码的问题,不幸的是我不熟悉Linux Bash编程,所以我尝试找不到一整天适用于我的任务的东西,并且希望你能指导我朝着正确的方向前进。

我有很多大文件,我想根据每个文件中的第三个字段进行拆分,我想在每个子文件中保留标题,并将创建的子文件保存在新创建的目录中从文件的根名称。

存储在原始目录中的初始文件是:

Downloads/directory1/Levels_CHG_Lab_S_sample1.txt
Downloads/directory1/Levels_CHG_Lab_S_sample2.txt
Downloads/directory1/Levels_CHG_Lab_S_sample3.txt

依旧......

每个文件都有200列,第3列包含1到10的值。 我想根据此列的值拆分上面的每个文件,并将子文件存储在子文件夹中,因此例如子文件夹“Downloads / directory1 / sample1”将包含10个文件(带有标题行)拆分文件Downloads / directory1 / Levels_CHG_Lab_S_sample1.txt。

我现在已经尝试了很多不同步骤来完成这些步骤,但是没有成功。我必须让它变得更复杂,因为我尝试的代码看起来很糟糕...... 以下是我尝试使用的代码:

FILES=Downloads/directory1/

for f in $FILES
  do
    # Create folder with root name by stripping file names
    fname=${echo $f | sed 's/.txt//;s/Levels_CHG_Lab_S_//'}
    echo "Creating sub-directory [$fname]"
    mkdir "$fname"

    # Save the header
    awk 'NR==1{print $0}' $f > header

    # Split each file by third column
    echo "Splitting file $f"
    awk  'NR>1  {print $0 > $3".txt" }' $f

    # Move newly created files in sub directory
    mv {1..10}.txt $fname  # I have no idea how to do specify the files just created

    # Loop through the sub-files to attach header row:
    for subfile in $fname
      do
       cat header $subfile >> tmp_file
       mv -f tmp_file $subfile
      done
done

所有这些步骤对我来说都很复杂,如果你能以正确的方式帮助我解决这个问题,我将非常感激。非常感谢您的帮助。 -fra

1 个答案:

答案 0 :(得分:1)

您现在的代码存在一些问题。首先,您列出下载目录的内容。您只需将FILES变量设置为该目录的路径的字符串。你需要这样的东西:

FILES=$(ls Downloads/directory1/*.txt)

您永远不会cdDownloads/directory1文件夹,因此您的mkdir会在cwd中创建目录;可能不是你想要的。

如果你知道第3列中的数字总是在1到10之间,我会在分割文件之前用标题行预先填充这些文件。

尝试使用此代码执行您想要的操作(未经测试):

BASEDIR=Downloads/directory1/
FILES=$(ls ${BASEDIR}/*.txt)

for f in $FILES; do
    # Create folder with root name by stripping file names
    dirname=$(echo $f | sed 's/.txt//;s/Levels_CHG_Lab_S_//')
    dirname="${BASENAME}/${dirname}/"
    echo "Creating sub-directory [$dirname]"
    mkdir "$dirname"

    # Save the header to each file
    HEADER_LINE=$(head -n1 $f)
    for i in {1..10}; do
      echo ${HEADER_LINE} > ${dirname}/${i}.txt
    done

    # Split each file by third column
    echo "Splitting file $f"
    awk -v dirname=${dirname} 'NR>1 {filename=dirname$3".txt"; print $0 >> filename }' $f
done