在两个string之间重复提取文本? (awk?sed?)

我有一个名为“plainlinks”的文件,如下所示:

13080. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94092-2012.gz 13081. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94094-2012.gz 13082. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94096-2012.gz 13083. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94097-2012.gz 13084. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94098-2012.gz 13085. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94644-2012.gz 13086. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94645-2012.gz 13087. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94995-2012.gz 13088. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94996-2012.gz 13089. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-96404-2012.gz 

我需要产生如下所示的输出:

 999999-94092 999999-94094 999999-94096 999999-94097 999999-94098 999999-94644 999999-94645 999999-94995 999999-94996 999999-96404 

Solutions Collecting From Web of "在两个string之间重复提取文本? (awk?sed?)"

使用sed

 sed -E 's/.*\/(.*)-.*/\1/' plainlinks 

输出:

 999999-94092 999999-94094 999999-94096 999999-94097 999999-94098 999999-94644 999999-94645 999999-94995 999999-94996 999999-96404 

要保存对文件的更改,请使用-i选项:

 sed -Ei 's/.*\/(.*)-.*/\1/' plainlinks 

或者保存到一个新文件,然后重定向:

 sed -E 's/.*\/(.*)-.*/\1/' plainlinks > newfile.txt 

说明:

 s/ # subsitution .* # match anything \/ # upto the last forward-slash (escaped to not confused a sed) (.*) # anything after the last forward-slash (captured in brackets) - # upto a hypen .* # anything else left on line / # end match; start replace \1 # the value captured in the first (only) set of brackets / # end 

只是为了好玩。

awk -F\/ '{print substr($7,0,12)}' plainlinks

或者用grep

grep -Eo '[0-9]{6}-[0-9]{5}' plainlinks

假设格式如前所述保持一致,可以使用awk

 awk 'BEGIN{FS="[/-]"; OFS="-"} {print $7, $8}' plainlinks > output_file 

输出:

 999999-94092 999999-94094 999999-94096 999999-94097 999999-94098 999999-94644 999999-94645 999999-94995 999999-94996 999999-96404 

说明

  • awk读取一行你的输入文件,将每一行分为“字段”
  • 'BEGIN{FS="[/-]"; OFS="-"} 'BEGIN{FS="[/-]"; OFS="-"}指定输入行上使用的分隔符应该是/- ,它还指定输出应该由-
  • {print $7, $8}'告诉awk打印每行的第7和第8个字段,在这个例子中是9999999xxxx
  • plainlinks是输入文件的名称将去的地方
  • > output_file将输出重定向到名为output_file的文件

只是壳的参数扩展:

 while IFS= read -r line; do tmp=${line##*noaa/} echo ${tmp%-????.gz} done < plainlinks 

如果格式保持不变,则不需要sed或awk:

 cat your_file | cut -d "/" -f 7- | cut -d "-" -f 1,2