【问题标题】:How do i cut section with start and end using Bash?如何使用 Bash 剪切带有开头和结尾的部分?
【发布时间】:2011-12-18 20:40:24
【问题描述】:

当我在做pactl list 时,我会得到很多信息。在这些信息中,我试图只从 Sink #0 开始直到该部分结束。

1) 信息的

Sink #0
    State: SUSPENDED
    Name: auto_null
    Description: Dummy Output
    Driver: module-null-sink.c
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Owner Module: 14
    Mute: no
    Volume: 0:   0% 1:   0%
            0: -inf dB 1: -inf dB
            balance 0.00
    Base Volume: 100%
                 0.00 dB
    Monitor Source: auto_null.monitor
    Latency: 0 usec, configured 0 usec
    Flags: DECIBEL_VOLUME LATENCY 
    Properties:
        device.description = "Dummy Output"
        device.class = "abstract"
        device.icon_name = "audio-card"

Source #0
    State: SUSPENDED
    Name: auto_null.monitor
    Description: Monitor of Dummy Output
    Driver: module-null-sink.c
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Owner Module: 14
    Mute: no
    Volume: 0:  80% 1:  80%
            0: -5.81 dB 1: -5.81 dB
            balance 0.00
    Base Volume: 100%
                 0.00 dB
    Monitor of Sink: auto_null
    Latency: 0 usec, configured 0 usec
    Flags: DECIBEL_VOLUME LATENCY 
    Properties:
        device.description = "Monitor of Dummy Output"
        device.class = "monitor"
        device.icon_name = "audio-input-microphone"

2) 我正在尝试,如:

#!/bin/bash
command=$(pactl list);
# just get Sink #0 section not one line 
Part1=$(grep "Sink #0" $command);
for i in $Part1
do
  # show only Sink #0 lines 
  echo $i;
done

3) 输出很奇怪

grep: dB: No such file or directory

如何使用我的 BASH 脚本获取该部分,还有其他最佳方法来处理此类过滤吗?

跟进:所以我也尽量保持简单。如:

pactl list | grep Volume | head -n1 | cut -d' ' -f2- | tr -d ' '
|________|   |________|    |______|   |_____________|  |_________|
  |            |                |              |           |
  command     target get    show 1 row      cut empty      Dont know..
  to list 

【问题讨论】:

  • 在脚本的新第二行使用 set -vx 打开 shell 调试,然后您可以看到 $command 中的值,如果事情按照您的方式工作,您现在就知道了/应该。祝你好运。
  • 优秀的帖子和跟进! (感谢接受投票!)祝你好运。

标签: linux bash fedora bash4


【解决方案1】:

您可以使用sed 编辑器的多个功能来实现您的目标。

 sed -n '/^Sink/,/^$/p'  pactl_Output.txt

-n 说“不要执行打印每一行输出的标准选项

/^Sink/,/^$/ 是一个范围正则表达式,表示查找以 Sink 开头的行,然后继续查看行,直到找到空行 (/^$/)。

最后一个字符,p 表示打印你匹配的内容。

如果空行中有空格或制表符,请使用" ...,/^$[${spaceChar}${tabChar}]*\$/p"。请注意从单引号到 dbl-quoting 的变化,这将允许变量 ${spaceChar} 和 ${tabChar} 扩展到它们的实际值。您可能需要转义结束的“$”。您需要在使用它们之前定义 spaceChar 和 tabChar,例如 spaceChar=" " 。在 S.O. 上没有办法。供您查看 tabChar,但并非所有 sed 都支持 \t 版本。您可以选择按 Tab 键或使用 \t。我会选择 Tab 键,因为它更便携。

虽然使用bash 可能实现您的目标,但sed 是为此类问题而设计的。

我希望这会有所帮助。

【讨论】:

  • 如果 shell 是 bash,您可以使用 $'\t' 作为制表符。因此sed -e 's/'$'\t''//g;' 将删除文件中的所有选项卡。
  • 可以使用管道轻松实现吗?例如:$ pactl 列表 | grep 卷 |头-n1 |剪切 -d' ' -f2- | tr -d''
  • 是的,pactl list | sed -n '/^Sink/,/^$/p'
  • 谢谢,我希望它更安全、更好。例如:pactl list | sed -n '/^Sink/,/^$/p' | grep Volume | head -n1 | cut -d' ' -f2- | tr -d ' '
【解决方案2】:

试试:

Part1=`echo $command | grep "Sink #0"`

而不是

Part1=$(grep "Sink #0" $command);

【讨论】:

  • 不必要地使用了 echo: grep "Sink #0" <<<"$command" - 尽管这样并不能真正解决问题。
猜你喜欢
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 2013-07-05
  • 2023-03-29
相关资源
最近更新 更多