Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 根据字段分割文件并保存在使用根名称创建的子目录中_Linux_Awk_Split - Fatal编程技术网

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

Linux 根据字段分割文件并保存在使用根名称创建的子目录中,linux,awk,split,Linux,Awk,Split,我在一些代码方面遇到了问题,不幸的是,我不是LinuxBash编程方面的专家,所以我一直试图找到一些适合我的任务的东西,但没有成功,我希望你能帮我找到正确的方向 我有许多大文件,我想根据每个文件中的第三个字段进行拆分,我想在每个子文件中保留标题,并将创建的子文件保存在根据文件根名称创建的新目录中 原始目录中存储的初始文件为: Downloads/directory1/Levels_CHG_Lab_S_sample1.txt Downloads/directory1/Levels_CHG_Lab_

我在一些代码方面遇到了问题,不幸的是,我不是LinuxBash编程方面的专家,所以我一直试图找到一些适合我的任务的东西,但没有成功,我希望你能帮我找到正确的方向

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

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

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\u CHG\u Lab\u S\u 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

您的代码现在有一些问题。首先,在任何时候都不要列出下载目录的内容。您只需将
FILES
变量设置为一个字符串,该字符串是该目录的路径。您将需要以下内容:

FILES=$(ls Downloads/directory1/*.txt)
您也从未将
cd
放入
Downloads/directory1
文件夹,因此您的
mkdir
将在
cwd
中创建目录;可能不是你想要的

如果您知道第3列中的数字总是在1到10之间,那么在拆分文件之前,我只需使用标题行预先填充这些文件

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


你好,伊巴雷尔,非常感谢你的帮助!!看起来你完全理解了我的问题,但是在尝试你的步骤时仍然有一些奇怪的事情发生:最后你的代码给了我10个前缀为“sample1”的子文件,以及一个只有标题的空文件的子文件夹,但看起来最后一个awk命令并没有达到预期的效果,也就是说,将子文件重定向到子文件夹,这样它也不会附加到带有标题的文件中…我尝试了这一行的变体filename=dirname$3.txt“,但似乎不起作用..如果你能发现为什么请在awk行告诉我,如果我使用filename=dirname$3.txt”已拆分的文件不会进入子目录,而如果我尝试使用类似${dirname}/$3这样的斜杠,我会得到一个错误“预期换行符或字符串结尾”,看起来您需要将尾部的
/
添加到第7行中设置的
dirname
变量集中,如下所示:
dirname=“${BASENAME}/${dirname}/”
。试试看。这也不行……如果我这样做,我会得到错误:“mkdir:cannotcreatedirectory`////////':File exists”哦,看起来我原来键入了第7行,但从未注意到。BASENAME应该读取BASEDIR,因为这是我们设置的变量。整行应该是
dirname=“${BASEDIR}/${dirname}/”
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