如何从 bash 中的不同输出保存在同一文件的两列中
How to save in two columns of the same file from different output in bash
我正在做一个项目,需要我输入一些 .bed,从每个文件中提取一列,只采用某些参数并计算每个文件有多少参数。我对 bash 非常缺乏经验,所以我不知道大部分命令。但是使用这行代码应该可以解决问题。
for FILE in *; do cat $FILE | awk '>1.3'| wc -l ; done>/home/parallels/Desktop/EP_Cell_Type.xls
我将这些值保存在 .xls 中,因为我需要用它们做一些图表。
现在我想用 -ls 获取文件名并将它们保存在我的 .xls 的第一列中,而我的参数应该在我的 excel 文件的第二列中。
我设法使用以下命令将所有内容保存在一列中:
ls>/home/parallels/Desktop/EP_Cell_Type.xls | for FILE in *; do cat $FILE | awk '>1.3'-x| wc -l ; done >>/home/parallels/Desktop/EP_Cell_Type.xls
我的示例文件 are:A549.bed, GM12878.bed, H1.bed, HeLa-S3.bed, HepG2.bed, Ishikawa.bed, K562.bed、MCF-7.bed、SK-N-SH.bed 并包含在仅包含这些文件的文件夹中。
输出是所有文件名的列表和同一列上的值,如下所示:
Column 1
A549.bed
GM12878.bed
H1.bed
HeLa-S3.bed
HepG2.bed
Ishikawa.bed
K562.bed
MCF-7.bed
SK-N-SH.bed
4536
8846
6754
14880
25440
14905
22721
8760
28286
但我需要的应该是这样的:
Filenames
#BS
A549.bed
4536
GM12878.bed
8846
H1.bed
6754
HeLa-S3.bed
14880
HepG2.bed
25440
Ishikawa.bed
14905
K562.bed
22721
MCF-7.bed
8760
SK-N-SH.bed
28286
假设 OP 的 awk
程序(正确地)找到了所有需要的行,一个更简单(更快)的解决方案可以完全写成 awk
.
一个 awk
解决方案跟踪匹配行数,然后打印文件名和行数:
awk '
FNR==1 { if ( count >= 1 ) # first line of new file? if line counter > 0
printf "%s\t%d\n", prevFN, count # then print previous FILENAME + tab + line count
count=0 # then reset our line counter
prevFN=FILENAME # and save the current FILENAME for later printing
}
>1.3 { count++ } # if field #9 > 1.3 then increment line counter
END { if ( count >= 1 ) # flush last FILENAME/line counter to stdout
printf "%s\t%d\n", prevFN, count
}
' * # * ==> pass all files as input to awk
出于测试目的,我将 >1.3
替换为 /do/
(匹配包含字符串 'do'
的任何行),并将 运行 替换为包含各种脚本和数据的目录文件。这生成了以下制表符分隔的输出:
bigfile.txt 7
blocker_tree.sql 4
git.bash 2
hist.bash 4
host.bash 2
lines.awk 2
local.sh 3
multi_file.awk 2
我正在做一个项目,需要我输入一些 .bed,从每个文件中提取一列,只采用某些参数并计算每个文件有多少参数。我对 bash 非常缺乏经验,所以我不知道大部分命令。但是使用这行代码应该可以解决问题。
for FILE in *; do cat $FILE | awk '>1.3'| wc -l ; done>/home/parallels/Desktop/EP_Cell_Type.xls
我将这些值保存在 .xls 中,因为我需要用它们做一些图表。 现在我想用 -ls 获取文件名并将它们保存在我的 .xls 的第一列中,而我的参数应该在我的 excel 文件的第二列中。 我设法使用以下命令将所有内容保存在一列中:
ls>/home/parallels/Desktop/EP_Cell_Type.xls | for FILE in *; do cat $FILE | awk '>1.3'-x| wc -l ; done >>/home/parallels/Desktop/EP_Cell_Type.xls
我的示例文件 are:A549.bed, GM12878.bed, H1.bed, HeLa-S3.bed, HepG2.bed, Ishikawa.bed, K562.bed、MCF-7.bed、SK-N-SH.bed 并包含在仅包含这些文件的文件夹中。
输出是所有文件名的列表和同一列上的值,如下所示:
Column 1 |
---|
A549.bed |
GM12878.bed |
H1.bed |
HeLa-S3.bed |
HepG2.bed |
Ishikawa.bed |
K562.bed |
MCF-7.bed |
SK-N-SH.bed |
4536 |
8846 |
6754 |
14880 |
25440 |
14905 |
22721 |
8760 |
28286 |
但我需要的应该是这样的:
Filenames | #BS |
---|---|
A549.bed | 4536 |
GM12878.bed | 8846 |
H1.bed | 6754 |
HeLa-S3.bed | 14880 |
HepG2.bed | 25440 |
Ishikawa.bed | 14905 |
K562.bed | 22721 |
MCF-7.bed | 8760 |
SK-N-SH.bed | 28286 |
假设 OP 的 awk
程序(正确地)找到了所有需要的行,一个更简单(更快)的解决方案可以完全写成 awk
.
一个 awk
解决方案跟踪匹配行数,然后打印文件名和行数:
awk '
FNR==1 { if ( count >= 1 ) # first line of new file? if line counter > 0
printf "%s\t%d\n", prevFN, count # then print previous FILENAME + tab + line count
count=0 # then reset our line counter
prevFN=FILENAME # and save the current FILENAME for later printing
}
>1.3 { count++ } # if field #9 > 1.3 then increment line counter
END { if ( count >= 1 ) # flush last FILENAME/line counter to stdout
printf "%s\t%d\n", prevFN, count
}
' * # * ==> pass all files as input to awk
出于测试目的,我将 >1.3
替换为 /do/
(匹配包含字符串 'do'
的任何行),并将 运行 替换为包含各种脚本和数据的目录文件。这生成了以下制表符分隔的输出:
bigfile.txt 7
blocker_tree.sql 4
git.bash 2
hist.bash 4
host.bash 2
lines.awk 2
local.sh 3
multi_file.awk 2