打印第一行部分,直到第一个空间

时间:2015-12-01 17:45:19

标签: linux bash

我有一个文件中所有卫星频道的列表。 我想只获得属于特定子频道的子频道。 ($i在以下示例中是基本channel1。)

该文件的原始内容:

B base channel1
C       child channel1
C       child channel2

B base channel2
C       child channel3

B base channel3 
C       child channel4

我只想得到:

child channel1
child channel2

我试过了:

cat /tmp/channel_list | grep -E -A10 '(^| )'$i'( |$)'| \
  grep -E -A10 '(^| )'$i'( |$)' | sed -n '/^B/,/^B/p' | \
  grep -v B | perl -i -pe 's/\s+\n/\n/' | sed 's/^ *//; s/ *$//; /^$/d'

产生:

C       child channel1
C       child channel2
C       child channel3

但我想要这个 - 我怎么才能得到这个呢?

child channel1
child channel2

4 个答案:

答案 0 :(得分:1)

假设你有一个包含字符串$i的shell变量base channel1,你可以使用这样的awk脚本:

awk -v channel="$i" '$0 ~ channel { f = 1; next } !NF { f = 0 } f { print $2, $3 }' file

当该行与存储在变量中的模式匹配时,设置标志f并且程序跳到下一行。如果没有字段(空行),则取消设置。设置标志后,打印第二个和第三个字段。

您可以通过重新排列块来避免使用next,因此f仅在匹配的行上选中后才会设置:

awk -v channel="$i" '!NF { f = 0 } f { print $2, $3 } $0 ~ channel { f = 1 }' file

答案 1 :(得分:0)

一种可能的解决方案是编写一个shell脚本,接受文件路径名作为第一个参数:


#!/bin/bash
i="base channel1"
while IFS='' read -r line || [[ -n "$line" ]]; do
        if echo $line | grep "$i" > /dev/null 2> /dev/null
        then
                while IFS='' read -r line && [[ -n "$line" ]]; do
                        echo $line | awk '{split($0,a,"C")} END{print a[1], a[2]}' | xargs
                done
                break
        fi
done 

Run the script as: script_name /tmp/channel_list

I get the following output:

    child channel1
    child channel2

Another possible way is: - with the first sed I select the block starting with the pattern and ending with the empty line - the second sed remove the blanck line - the third remove the initiali "C " prefix

 
sed -n "/^B $i/,/^\s*\$/{1d;p;}" /tmp/channel_list | sed '$ d' | sed 's/^C *//g'

答案 2 :(得分:0)

使用sed获取$ i和空行之间的内容, 然后切掉不想要的'

cat test|sed -n "/$i/{:a;n;/^\s*$/b;p;ba}"|cut -c 9-

输出:

child channel1
child channel2

答案 3 :(得分:0)

上面提到的最后一个sed链为我工作:

仅列出卫星子频道频道:

$i是基础channel1

rhn-satellite-exporter --list-channels |grep -E -A10 '(^| )'$i'( |$)'|sed -n "/B $i/,/^\s/{1d;p}"| sed '$ d' |sed 's/^C *//g'|awk '{print $1}'

<强>输出:

子频道1

儿童频道2