我遇到了几段代码的问题,不幸的是我不熟悉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
答案 0 :(得分:1)
您现在的代码存在一些问题。首先,您列出下载目录的内容。您只需将FILES
变量设置为该目录的路径的字符串。你需要这样的东西:
FILES=$(ls Downloads/directory1/*.txt)
您永远不会cd
到Downloads/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