我有一个文件中所有卫星频道的列表。
我想只获得属于特定子频道的子频道。
($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
答案 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