在图案后提取线条

时间:2019-04-03 22:17:11

标签: awk sed

我在一个文件夹中有50个文件,并且所有文件都有一个通用模式“ ^^”。我想在“ ^^”之后打印所有内容,并附加文件名,然后将所有提取的行打印到一个输出文件中。虽然我的代码可以在单个文件上正常运行,但不适用于所有文件。

awk '/\^^/{getline; getline; print FILENAME; print}' *.txt > output

示例

1.txt

     ghghh hghg 
       ghfg hghg hjg
            jhhkjh 
    kjhkjh kjh

^^ 
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

2.txt

hghjhg hgj 
 jhgj

            jhgjh kjgh

        jhg

^^ 
bbbbbbbbbbbbbbbbbbbbbbb

所需的output.txt

1.txt
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2.txt
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

我的实际输出

1.txt
ghghh hghg
1.txt
zzzzzzzzzzzzzzzzzzzzzzzzzzzzz

8 个答案:

答案 0 :(得分:1)

要在^^之后打印行,请尝试:

$ awk 'f{print FILENAME ORS $0; f=0} /\^\^/{f=1}' *.txt
1.txt
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2.txt
bbbbbbbbbbbbbbbbbbbbbbb

工作原理:

  • f{print FILENAME ORS $0; f=0}

    如果变量f为true(非零),则打印文件名,输出记录分隔符和当前行。然后将f设为零。

  • /\^\^/{f=1}

    如果当前行包含^^,请将f设置为1。

答案 1 :(得分:1)

$ awk 'FNR==1{print FILENAME; f=0} f; $1=="^^"{f=1}' *.txt
1.txt
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2.txt
bbbbbbbbbbbbbbbbbbbbbbb

答案 2 :(得分:0)

我喜欢一种更“扑朔迷离”的方法。

grep -Hn '^^' *.txt |
cut -d: -f1,2 --output-delimiter=' ' |
while read f n; do echo $f; tail $f -n+$((n+1)); done
  • grep -Hn会告诉您图案的行号。
  • 通过cut,我们仅根据需要获取所需的字段。
  • 在一个循环中,我们将read的两个信息tail转换为变量,以根据需要自由使用它们。
  • 如果使用加号信号,N不仅可以读取最后的+N行,还可以读取$((...))中的所有行。
  • 我们可以在Unit1 Unit2 Rate ---------------------- box bottle 20 bottle gallon 30 gallon bottle 1/30 内进行算术运算以跳过图案线。

它可以解决您的问题。而且它可以在模式之后打印所有行,而不仅仅是下一行。

答案 3 :(得分:0)

使用awk

awk 'FNR==1{print FILENAME} FNR==1,/\^\^/{next}1' *.txt

位置:

  • 当FNR == 1时打印文件名
  • FNR==1,/\^\^/{next}:将跳过FNR == 1和匹配^^的第一行之间的所有行
  • 1最后在匹配的^^行之后打印其余行

答案 4 :(得分:0)

让您的文件名介于1到50之间,且为txt类型

for f in {1..50}.txt
{
  sed -nE "/^\^\^\s*$/{N;s/.+\n(.+)/$f\n\1/p}" $f>$f.result.txt
}

答案 5 :(得分:0)

仅当我们具有与模式匹配的文件时,以下输出:

awk 'FNR==1 { f=0 }; f; /\^\^/ { f=1; print FILENAME }' *.txt > output
  1. 在每个新文件上重置标志f
  2. 如果设置了f,则打印。
  3. 如果我们匹配模式,则设置fprint FILENAME

无论匹配的模式如何,此命令都会打印出FILENAME

awk 'FNR==1 { f=0; print FILENAME }; f; /\^\^/ { f=1 }' *.txt > output

我们可以根据需要调整步骤3中的模式匹配。例如,可以使用$0=="^^"进行精确匹配。

答案 6 :(得分:0)

从对这个主题的上一个问题的某些答案和评论中删除,您还可以使用grep -A并使用sed格式化输出。

$ grep -A100 '^^' *.txt | sed '/\^^/d;/--/d;s/-/\n/'
1.txt
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2.txt
bbbbbbbbbbbbbbbbbbbbbbb

假设100行就足够了,并且您没有连字符。

如果只需要一行,请使用-A1

答案 7 :(得分:0)

这可能对您有用(GNU sed):

sed -s '1,/^^^/{/^^^/F;d}' file1 file2 file3 ... >fileOut