在bash中提取两个字符之间的字符串

时间:2012-07-07 20:18:45

标签: string bash sed awk

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

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中的文字只是一种矫枉过正。那么,有没有更好或更短的方法来实现这一目标。

8 个答案:

答案 0 :(得分:3)

将字段拆分为磅并将字符斜线转换为数组并检索所需的元素。

awk 'NR==2 {split($2, arr, "[#/]"); print arr[2]}'

答案 1 :(得分:3)

这个答案利用bash的内置扩展正则表达式语法,使用=~测试运算符。 (我说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数组的第0个元素中。

答案 2 :(得分:2)

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

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

输出:

36

答案 3 :(得分:2)

这可能对您有用:

sed 's/.*#\([0-9]*\)\/[0-9]*.*/\1/p;d' file
36

答案 4 :(得分:2)

input | while read playing numbers rest
do
  if [[ $playing = "[playing]" ]]; then
    t="${numbers:1}"
    echo "${t%/*}"
  fi
done

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

答案 5 :(得分:2)

sed -n '2s/.*\#\([0-9]*\)\/.*/\1/p'

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

之间的数字

答案 6 :(得分:1)

这可以解决您的问题。

awk -F'[#/]' 'NR==2{print $2}'

答案 7 :(得分:0)

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

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

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