5

我有一个格式如下的字符串

Walk Off the Earth - Somebody That I Used to Know
[playing] #36/37   1:04/4:05 (26%)
volume: n/a   repeat: off   random: on    single: off   consume: off

现在,我需要从上面的字符串中36提取#36/37.

我做的第一件事是#36/37使用从第二行中提取

echo "above mentioned string" | awk 'NR==2 {print $2}'

现在,我想36从上面提取的部分中提取我所做的

echo `#36/37` | sed -e 's/\//#/g' | awk -F "#" '{print $2}'

这给了我36作为我的输出。

但是,我觉得同时使用两者sed and awk只是为了从中提取文本#36/37是矫枉过正的。那么,有没有更好或更短的方法来实现这一点。

4

8 回答 8

5

将磅和斜线字符上的字段拆分为一个数组并检索所需的元素。

awk 'NR==2 {split($2, arr, "[#/]"); print arr[2]}'
于 2012-07-07T20:30:55.707 回答
3

=~这个答案利用了 bash 使用test 运算符的内置扩展正则表达式语法。(我说test,但不要指望它与test命令一起使用。它只与[[关键字一起使用。)

mini:~ michael$ cat foo
Walk Off the Earth - Somebody That I Used to Know
[playing] #36/37   1:04/4:05 (26%)
volume: n/a   repeat: off   random: on    single: off   consume: off

mini:~ michael$ [[ $(<foo) =~ \#[[:digit:]]{2} ]] && echo "${BASH_REMATCH[0]#\#}"
36

当你把它归结起来时,这只是一个匹配井号后两位数字的正则表达式,并将它们保存在BASH_REMATCH数组的第零个元素中。

于 2012-07-07T20:47:48.597 回答
2

这将解决您的问题。

awk -F'[#/]' 'NR==2{print $2}'
于 2012-07-09T11:43:36.930 回答
2

使用sed假设的一种方法infile是问题的内容。在第二行匹配任何字符直到#,然后将任何数字保存在第 1 组中,并用该组替换整行\1。除非在代码-n中用指令指示,否则该开关会避免打印任何内容。p

sed -ne '2 { s/^[^#]*#\([0-9]*\).*$/\1/; p; q }' infile

输出:

36
于 2012-07-07T20:28:26.887 回答
2

这可能对您有用:

sed 's/.*#\([0-9]*\)\/[0-9]*.*/\1/p;d' file
36
于 2012-07-07T20:33:15.790 回答
2
input | while read playing numbers rest
do
  if [[ $playing = "[playing]" ]]; then
    t="${numbers:1}"
    echo "${t%/*}"
  fi
done

Bash 默认拆分是按空格,所以你在第二个字段(数字)中得到的就是那个数字。剩下的就是使用 bash 参数扩展运算符来获取感兴趣的部分:删除第一个字符并删除以“/”开头的后缀

于 2012-07-07T20:33:29.357 回答
2
sed -n '2s/.*\#\([0-9]*\)\/.*/\1/p'

这会抑制除第二行之外的所有内容,然后回显和之间的#数字/

于 2012-07-07T20:41:21.300 回答
0

我编写了一个脚本,它输出第一个字符和最后一个字符之间的字符串。要解决您的问题,您可以使用以下命令与此脚本结合使用。

echo '[playing] #36/37   1:044:05 (26%)' | cut -d' ' -f2 | ./cut_between.sh -f '#' -l '/'

您可以在GitHub 上下载此脚本。

于 2013-02-22T08:13:26.633 回答