如何在某些标签之间打印数据?

时间:2017-03-22 09:58:21

标签: bash unix awk sed pattern-matching

我有一组带有这种数据的文件(数百个)(管道作为列分隔符):

000|FILE___V20170307-003792
102|000|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|0001|KLJDFLKJBDL|00|ADGAHA||00|ASYAHA|||DAGHAH|0|GAFDGA|18||3|N|1||AHA|ASGAN|ASFAN||82|1||2|300|||0|0|0|0|10|0||0|0|KLJDFLKJBDL|2||||||||
102|0100|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|00|KLJDFLKJBDL|00|ASDGAHA||00|ASYAHA|||DAGHAH|0|AGAH|5||3|N|1||AHA|ASGAN|ASDHAH||82|1||2|300|||0|0|0|0|54|0||0|0|KLJDFLKJBDL|2||||||||
010|ENDOFFILE|10

如何只在第一行和最后一行之间使用行?第一行的第一行有000,第一行的第一行有010。我尝试使用awk:

awk '/000/,/010/ { print > "output.txt" }' input_file.txt

但它不起作用,也没有检查第一列是否找到了000和010。也许以某种方式省略第一行和最后一行也有效?

5 个答案:

答案 0 :(得分:1)

您可以使用此sed

sed -n '/^000|/,/^010|/{/^0[01]0|/!p;}' file

102|000|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|0001|KLJDFLKJBDL|00|ADGAHA||00|ASYAHA|||DAGHAH|0|GAFDGA|18||3|N|1||AHA|ASGAN|ASFAN||82|1||2|300|||0|0|0|0|10|0||0|0|KLJDFLKJBDL|2||||||||
102|0100|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|00|KLJDFLKJBDL|00|ASDGAHA||00|ASYAHA|||DAGHAH|0|AGAH|5||3|N|1||AHA|ASGAN|ASDHAH||82|1||2|300|||0|0|0|0|54|0||0|0|KLJDFLKJBDL|2||||||||

find命令中使用:

find . -name '*.txt' -exec sed -i '' -n '/^000|/,/^010|/{/^0[01]0|/!p;}' {} \;

答案 1 :(得分:1)

你可以尝试,

awk -v FS="|" '$1=="000",$1=="010" {print > "output.txt"}' input_file.txt

你明白了,

000|FILE___V20170307-003792
102|000|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|0001|KLJDFLKJBDL|00|ADGAHA||00|ASYAHA|||DAGHAH|0|GAFDGA|18||3|N|1||AHA|ASGAN|ASFAN||82|1||2|300|||0|0|0|0|10|0||0|0|KLJDFLKJBDL|2||||||||
102|0100|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|00|KLJDFLKJBDL|00|ASDGAHA||00|ASYAHA|||DAGHAH|0|AGAH|5||3|N|1||AHA|ASGAN|ASDHAH||82|1||2|300|||0|0|0|0|54|0||0|0|KLJDFLKJBDL|2||||||||
010|ENDOFFILE|10

only rows between the first row and the last row

awk -v FS="|" '$1=="010"{f=0} f{print > "output.txt"} $1=="000"{f=1}' input_file.txt

你明白了,

102|000|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|0001|KLJDFLKJBDL|00|ADGAHA||00|ASYAHA|||DAGHAH|0|GAFDGA|18||3|N|1||AHA|ASGAN|ASFAN||82|1||2|300|||0|0|0|0|10|0||0|0|KLJDFLKJBDL|2||||||||
102|0100|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|00|KLJDFLKJBDL|00|ASDGAHA||00|ASYAHA|||DAGHAH|0|AGAH|5||3|N|1||AHA|ASGAN|ASDHAH||82|1||2|300|||0|0|0|0|54|0||0|0|KLJDFLKJBDL|2||||||||

答案 2 :(得分:1)

要在第一行和最后一行之间获取而不考虑内容,请使用awk:

$ awk 'NR>2{print p} {p=$0}' file
102|000|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|0001|KLJDFLKJBDL|00|ADGAHA||00|ASYAHA|||DAGHAH|0|GAFDGA|18||3|N|1||AHA|ASGAN|ASFAN||82|1||2|300|||0|0|0|0|10|0||0|0|KLJDFLKJBDL|2||||||||
102|0100|DDKSB=DAGA;DAGA=ADGA;DAG-FGSA=ADGA|00|KLJDFLKJBDL|00|ASDGAHA||00|ASYAHA|||DAGHAH|0|AGAH|5||3|N|1||AHA|ASGAN|ASDHAH||82|1||2|300|||0|0|0|0|54|0||0|0|KLJDFLKJBDL|2||||||||

使用headtail

$ head -n -1 file |tail -n +2

man head

   -n, --lines=[-]K
          print the first K lines instead of the first 10; with the 
          leading '-', print all but the last K lines of each file

man tail

   -n, --lines=K
          output the last K lines, instead of the last 10; or use -n +K to 
          output lines starting with the Kth

如果您有多个文件,可以:

for f in files* ; do head -n -1 "$f" |tail -n +2 > newpath/"$f" ; done

答案 3 :(得分:1)

sed的另一种方法:

sed -n '/^000/,/^010/{//d;p}' file
  • /^000/,/^010/:从000开始的行到以010开头的下一行
  • //d:删除与上述地址范围内的模式匹配的行
  • p:输出模式空间

答案 4 :(得分:0)

我会在类似C的'中写更多内容。方式:

 awk 'BEGIN{ ok = 0; FS = "|" } { if( $1 == "000" && ok == 0 ) { ok = 1; } if( ok == 1 ) { print; } if( $1 == "010" ) { ok = -1; } }' file
相关问题