你如何删除每一行,但是那些以几个特定单词之一开头? bash脚本

时间:2015-06-11 14:00:22

标签: bash sed

我正在寻找一个命令,它允许我从变量中删除所有内容,但是以几个特定单词之一开头的行。

我看了很多sed命令,但我根本无法解决问题。我要么退还了!而不是所需单词中的第一个字符,而只是从(在这种情况下单个)其他行中删除的最后一个字符。

以下仅仅是我尝试过的一个例子 - 这意味着我不会寻找方法本身的替代方案。只有如何从除给定行之外的所有内容中清除变量!

distro_raw="lsb_release -si"
distro=`echo $distro_raw | sed -r '/ubuntu/!d'`

我尝试过其他方式(不使用-r,而是使用'/ s // g')。我只是想用代码来举例说明我想要的东西。这显然是错误的,但可能会使问题更加明确。

编辑:

一个更清晰的例子:

server_file=`cat /etc/apt/sources.list`
server`echo $server_file | sed ${what_to_write_before}deb${what_to_write_after}`

然后将删除除“server”之外的所有内容。我不知道的是如何使用“deb”这个词 - 所以命令只返回以“deb”开头的行

示例输入:

# deb cdrom:[Ubuntu-Server 14.10 _Utopic Unicorn_ - Release amd64 (20141022.2)]/ utopic main restricted

# deb cdrom:[Ubuntu-Server 14.10 _Utopic Unicorn_ - Release amd64 (20141022.2)]/ utopic main restricted

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://dk.archive.ubuntu.com/ubuntu/ vivid main restricted
deb-src http://dk.archive.ubuntu.com/ubuntu/ vivid main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://dk.archive.ubuntu.com/ubuntu/ vivid-updates main restricted
deb-src http://dk.archive.ubuntu.com/ubuntu/ vivid-updates main restricted

想要的输出是

deb http://dk.archive.ubuntu.com/ubuntu/ vivid main restricted
deb-src http://dk.archive.ubuntu.com/ubuntu/ vivid main restricted
deb http://dk.archive.ubuntu.com/ubuntu/ vivid-updates main restricted
deb-src http://dk.archive.ubuntu.com/ubuntu/ vivid-updates main restricted

3 个答案:

答案 0 :(得分:5)

不要捕获文件的内容并设置管道 - 只需指向grep(或sedawk,或任何其他可以过滤的文本处理工具正则表达式直接针对您的文件,使用^将正则表达式锚定到该行的前面:

result=$(grep -E '^deb' </etc/apt/sources.list)

现在,如果你有更多的单词而不仅仅是“deb”,那么交替是合适的:

result=$(grep -E '^(deb|foo|bar)' </etc/apt/sources.list)

那就是说,如果你想要文件中的所有非评论内容,我就不会这样做了:只需过滤掉评论和空白行(包括删除评论后空白的行):

sed -e 's/#.*//' </etc/apt/sources.list | grep -E -v '^[[:space:]]*'

最后,为了您的娱乐,这里的纯粹bash方法确实只提取服务器名称,而不是将整行放入名为server的变量中,并过滤它们以获得唯一性:

# Collect server URLs into an associative array
declare -A servers=( )
while read -r; do
  line=${REPLY%%#*}
  [[ $line ]] || continue
  read -r type url repos <<<"$line"
  echo "Found a line of type $type with url $url for repos $repos" >&2
  servers["$url"]=$repos
done </etc/apt/sources.list

# Iterate over the servers we found:
for server in "${!servers[@]}"; do
  echo "$server"
done

答案 1 :(得分:1)

阅读问题标题

sed -n '/^one\|^two\|^three/p' file  

将保持以一两个或三个

开头的行
sed '/^one\|^two\|^three/d' file

将删除以这些词开头的行

答案 2 :(得分:0)

使用您在问题中提供的示例,这可能就像

一样简单
sed '/ubuntu/!d' /etc/apt/sources.list

示例输出:

deb http://gb.archive.ubuntu.com/ubuntu/ trusty main restricted
deb-src http://gb.archive.ubuntu.com/ubuntu/ trusty main restricted
deb http://gb.archive.ubuntu.com/ubuntu/ trusty-updates main restricted
deb-src http://gb.archive.ubuntu.com/ubuntu/ trusty-updates main restricted
deb http://gb.archive.ubuntu.com/ubuntu/ trusty universe
deb-src http://gb.archive.ubuntu.com/ubuntu/ trusty universe
deb http://gb.archive.ubuntu.com/ubuntu/ trusty-updates universe
deb-src http://gb.archive.ubuntu.com/ubuntu/ trusty-updates universe
...
# deb-src http://extras.ubuntu.com/ubuntu trusty main