我正在尝试在目录中的几个文件的内容中执行一些grep并将我的grep匹配附加到单个文件中,在我的输出中我还想要一个具有文件名的列,以便从哪些文件中了解进入了。我试图使用awk但它没有用。
for i in *_2.5kb.txt; do more $i | grep "NM_001080771" | echo `basename $i` | awk -F'[_.]' '{print $1"_"$2}' | head >> prom_genes_2.5kb.txt; done
文件名是这样的,我有大约50个文件
48hrs_CT_merged_peaks_2.5kb.txt
48hrs_TAMO_merged_peaks_2.5kb.txt
72hrs_TAMO_merged_peaks_2.5kb.txt
72hrs_CT_merged_peaks_2.5kb.txt
5D_CT_merged_peaks_2.5kb.txt
5D_TAMO_merged_peaks_2.5kb.txt
每个文件内容有几行
chr1 3663275 3663483 14 2.55788 2.99631 1.40767 NM_001011874 -
chr1 4481687 4488063 264 7.85098 28.25170 26.41094 NM_011441 -
chr1 5008006 5013929 243 8.20677 26.17854 24.37907 NM_021374 -
chr1 5578362 5579949 65 3.48568 7.83501 6.57570 NM_011011 +
chr1 5905702 5908002 148 5.84647 16.53171 14.88463 NM_010342 -
chr1 9288507 9290352 77 4.04459 9.12442 7.77642 NM_027671 -
chr1 9291742 9292528 142 5.74749 16.21792 14.28185 NM_027671 -
chr1 9535689 9536176 72 4.45286 8.82567 7.29563 NM_021511 +
chr1 9535689 9536176 72 4.45286 8.82567 7.29563 NM_175236 +
chr1 9535689 9536176 72 4.45286 8.82567 7.29563 NR_027664 +
当我获得"NM_001080771"
的匹配时,我将该行的全部内容打印到新文件,并且对于每个文件,此操作正在完成,并将匹配附加到一个输出文件。我还想在最终输出中添加一个带有文件名的列,如上所示,以便我知道从哪个文件获取条目。
期望的输出
chr4 21610972 21618492 193 7.28409 21.01724 19.35525 NM_001080771 - 48hrs_CT
chr4 21605096 21618696 76 4.22442 9.32981 7.68131 NM_001080771 - 48hrs_TAMO
chr4 21604864 21618713 12 1.78194 2.36793 1.25883 NM_001080771 - 72hrs_CT
chr4 21610305 21615717 26 2.90579 4.47333 2.65353 NM_001080771 - 72hrs_TAMO
chr4 21609924 21618600 23 2.63778 4.0642 2.33685 NM_001080771 - 5D_CT
chr4 21609936 21618680 30 5.63778 3.0642 8.33685 NM_001080771 - 5D_TAMO
这不起作用。我想基本上附加一个列,其中文件名也应该作为条目添加到第一列或最后一列。怎么做?
答案 0 :(得分:3)
或者您可以在awk
awk '/NM_001080771/ {print $0, FILENAME}' *_2.5kb.txt
以所需格式修剪文件名
$ awk '/NM_001080771/{sub(/_merged_peaks_2.5kb.txt/,"",FILENAME);
print $0, FILENAME}' *_2.5kb.txt
答案 1 :(得分:0)
只要文件数量不大,为什么不呢:
grep NM_001080771 *_2.5kb.txt | awk -F: '{print $2,$1}'
如果你有太多的文件可以使用,这里是一个基于脚本的方法,使用awk附加文件名:
#!/bin/sh
for i in *_2.5kb.txt; do
< $i grep "NM_001080771" | \
awk -v where=`basename $i` '{print $0,where}'
done
./thatscript | head > prom_genes_2.5kb.txt
这里我们使用awk的-v VAR=VALUE
命令行功能传递文件名(因为我们使用stdin,我们在awk的内置FILENAME变量中没有任何用处)。
你也可以在@ karakfa优雅的awk-only方法中使用这样的循环:
#!/bin/sh
for i in *_2.5kb.txt; do
awk '/NM_001080771/ {print $0, FILENAME}' $i
done
最后,这是一个具有所需文件名的版本:
#!/bin/sh
for i in *_2.5kb.txt; do
awk -v TAG=${i%_merged_peaks_2.5kb.txt} '/NM_001080771/ {print $0, TAG}' $i
done
(这使用shell的变量替换${variable%pattern}
从pattern
的末尾修剪variable
猜测你以后可能想要搜索其他字符串,那么为什么我们不这样传入搜索字符串:
#!/bin/sh
what=${1?Need search string}
for i in *_2.5kb.txt; do
awk -v TAG=${i%_merged_peaks_2.5kb.txt} /${what}/' {print $0, TAG}' $i
done
./thatscript NM_001080771 | head > prom_genes_2.5kb.txt
或者,如果您有过于复杂和迂腐引用事物的病态需求,即使是在5行“一次性”脚本中:
#!/bin/sh
shopt -s nullglob
what="${1?Need search string}"
filematch="*_2.5kb.txt"
trimsuffix="_merged_peaks_2.5kb.txt"
for filename in $filematch; do
awk -v tag="${filename%${trimsuffix}}" \
-v what="${what}" \
'$0 ~ what {print $0, tag}' $filename
done