【问题标题】:Print a range of lines onto one line in awk在 awk 中将一系列行打印到一行上
【发布时间】:2013-10-21 20:28:37
【问题描述】:

我需要将匹配范围的行打印到一行上。

文件包含:

banana
start
1
2
3
stop
banana
banana
start
5
6
stop

我需要将其输出为

start 1 2 3 stop
start 5 6 stop

我目前正在使用基本的/start/,/stop/{print $0} 语法来获取我的范围,但是 我正在寻找带有awk 的语法,它将在单行上输出我的范围。 (为清楚起见进行了编辑)

【问题讨论】:

  • 我给了这个一个减号,因为请求被改变了。这使得对您请求的所有回答都无效。
  • 我认为最初的意图是隐含的,因为我使用的是匹配范围,而不是用正则表达式或其他东西进行巧妙的搜索和替换逻辑。抱歉“更改”。

标签: awk


【解决方案1】:

这应该可以工作

awk '/start/,/stop/{if($0 ~ /stop/){print}; if($0 !~ /stop/){printf $0" "}}' file

【讨论】:

  • 你不需要分号;
  • 您应该始终指定printf 的格式并将printf $0 " " 更改为printf "%s ",$0。如果文件确实包含 eks %s 这将失败。
  • 这给了我:香蕉香蕉香蕉开始(换行)1 2 3香蕉香蕉开始(换行)4 5 6香蕉...换句话说,它忽略了我的范围,只是省略了我范围的最后一行。
  • @wolfmason,呵呵,你从哪儿弄来的香蕉
  • 它们从“不需要的信息”树中掉到我的文件中,因此我使用匹配范围来忽略它们。
【解决方案2】:
awk '{ORS = $1 == "stop" ? "\n" : " "; print}'

【讨论】:

    【解决方案3】:

    gnu awk 版本(由于某些 awk 的 RS 限制)

    awk '$1=$1 {print $0,RS}' RS="stop" file
    

    更强大的版本

    awk '{$1=$1} $0 {print $0,RS}' RS="stop" file
    

    这应该适用于所有awk 版本

    awk '/stop/ {print;next} {printf "%s ",$0}' file
    

    香蕉版

    awk '/start/ {f=1} f {s=s?s" "$0:$0} /stop/ {print s;f=s=0}' file
    

    【讨论】:

      【解决方案4】:
      gawk '$1 ~ /^start$/{in_range = 1; ORS = " ";} $1 ~ /^stop/{in_range = 0; ORS = "\n"; print $0; next;} in_range{print $0}' test2.txt
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-24
        • 1970-01-01
        相关资源
        最近更新 更多