文件名如何作为输出中的列?

时间:2016-03-03 15:12:23

标签: awk sed grep

我正在尝试在目录中的几个文件的内容中执行一些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

这不起作用。我想基本上附加一个列,其中文件名也应该作为条目添加到第一列或最后一列。怎么做?

2 个答案:

答案 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