Regex 如何在OSX上使用sed提取子字符串?

Regex 如何在OSX上使用sed提取子字符串?,regex,macos,bash,sed,Regex,Macos,Bash,Sed,我试图遍历目录中的每个文件和文件夹,并将部分文件名提取到变量中,但我无法使sed正常工作。我要么得到所有文件名,要么一个也得不到 此版本的脚本应捕获整个文件名: #!/bin/bash for f in * do substring=`echo $f | sed -E -n 's/(.*)/\1/'` echo "sub: $substring" done sub: Adlm sub: Applications sub: Applications (Parallels) sub

我试图遍历目录中的每个文件和文件夹,并将部分文件名提取到变量中,但我无法使sed正常工作。我要么得到所有文件名,要么一个也得不到

此版本的脚本应捕获整个文件名:

#!/bin/bash
for f in *
do
    substring=`echo $f | sed -E -n 's/(.*)/\1/'`
    echo "sub: $substring"
done
sub: Adlm
sub: Applications
sub: Applications (Parallels)
sub: Desktop
...
但我什么也得不到:

sub:
sub:
sub:
sub:
...
此版本应仅提供文件名中的第一个字符:

#!/bin/bash
for f in *
do
    substring=`echo $f | sed -E 's/^([a-zA-Z])/\1/'`
    echo "sub: $substring"
done
但我得到的是整个文件名:

#!/bin/bash
for f in *
do
    substring=`echo $f | sed -E -n 's/(.*)/\1/'`
    echo "sub: $substring"
done
sub: Adlm
sub: Applications
sub: Applications (Parallels)
sub: Desktop
...
我已经尝试过多次迭代,它基本上归结为,如果我使用
-n
我什么也得不到,如果我不使用,我会得到整个文件名

有人能告诉我如何得到第一个角色吗

或者,我的总体目标是能够提取一个子字符串并将其存储到一个变量中,如果有人有更好的方法,我也会很感激


提前感谢。

您忘记在sed中的捕获组之后添加
*

$ for i in *; do substring=`echo $i | sed -E 's/^(.).*$/\1/'`; echo "sub: $substring"; done

最好使用
而不是
[a-zA-Z]
,因为如果第一个字符以任何特殊字符开头,则可能会失败。

您忘记在sed中的捕获组之后添加
*

$ for i in *; do substring=`echo $i | sed -E 's/^(.).*$/\1/'`; echo "sub: $substring"; done

最好使用
而不是
[a-zA-Z]
,因为如果第一个字符以任何特殊字符开头,则可能会失败。

如果要修改shell参数,可能需要使用参数扩展

for f in *; do
    # This version should expand to the whole parameter
    echo "$f"
    # This version should expand to the first character in the filename
    echo "${f::1}"
done
参数扩展没有sed强大,但它们内置于shell中(无需启动单独的进程或子shell),并且有以下扩展:

  • 子字符串(如上所述)
  • 替换和替换字符
  • 更改字符串的大小写(bash 4+)

  • 等等。

    如果要修改shell参数,可能需要使用参数展开

    for f in *; do
        # This version should expand to the whole parameter
        echo "$f"
        # This version should expand to the first character in the filename
        echo "${f::1}"
    done
    
    参数扩展没有sed强大,但它们内置于shell中(无需启动单独的进程或子shell),并且有以下扩展:

  • 子字符串(如上所述)
  • 替换和替换字符
  • 更改字符串的大小写(bash 4+)

  • 还有更多。

    我更喜欢awk而不是sed。这对我来说似乎更容易理解

    #!/bin/bash
    #set -x
    for f in *
    do
      substring=`echo $f | awk '{print substr($1,1,1)}'`
      echo "sub: $substring"
    done
    

    我喜欢awk而不是sed。这对我来说似乎更容易理解

    #!/bin/bash
    #set -x
    for f in *
    do
      substring=`echo $f | awk '{print substr($1,1,1)}'`
      echo "sub: $substring"
    done
    
    此版本的脚本应捕获整个文件名:

    #!/bin/bash
    for f in *
    do
        substring=`echo $f | sed -E -n 's/(.*)/\1/'`
        echo "sub: $substring"
    done
    
    sub: Adlm
    sub: Applications
    sub: Applications (Parallels)
    sub: Desktop
    ...
    
    sed-E-n's/(.*)/\1/'

    但是我什么也得不到

    您使用了
    -n
    ,因此它自然不会产生任何结果。也许您应该删除
    -n
    或添加
    p

    sed -E -n 's/(.*)/\1/p'
    
    此版本应仅提供文件名中的第一个字符:

    #!/bin/bash
    for f in *
    do
        substring=`echo $f | sed -E 's/^([a-zA-Z])/\1/'`
        echo "sub: $substring"
    done
    
    sed-E's/^([a-zA-Z])/\1/'

    但是我得到了整个文件名

    你没有替换那里的任何东西。也许你想要的是

    sed -E 's/^([a-zA-Z]).*/\1/'
    
    此外,我建议引用你的论点:

    substring=`echo "$f" | sed ...'`
    
    最后,如果您使用的是Bash,那么更简单的方法是使用子字符串扩展

    此版本的脚本应捕获整个文件名:

    #!/bin/bash
    for f in *
    do
        substring=`echo $f | sed -E -n 's/(.*)/\1/'`
        echo "sub: $substring"
    done
    
    sub: Adlm
    sub: Applications
    sub: Applications (Parallels)
    sub: Desktop
    ...
    
    sed-E-n's/(.*)/\1/'

    但是我什么也得不到

    您使用了
    -n
    ,因此它自然不会产生任何结果。也许您应该删除
    -n
    或添加
    p

    sed -E -n 's/(.*)/\1/p'
    
    此版本应仅提供文件名中的第一个字符:

    #!/bin/bash
    for f in *
    do
        substring=`echo $f | sed -E 's/^([a-zA-Z])/\1/'`
        echo "sub: $substring"
    done
    
    sed-E's/^([a-zA-Z])/\1/'

    但是我得到了整个文件名

    你没有替换那里的任何东西。也许你想要的是

    sed -E 's/^([a-zA-Z]).*/\1/'
    
    此外,我建议引用你的论点:

    substring=`echo "$f" | sed ...'`
    


    最后,一个更简单的方法是使用子字符串扩展,如果您按照的建议使用Bash。

    我认为您想要
    grep-o
    而不是sed。您不应该使用旧的和过时的backtics。像这样使用括号
    var=$(code)
    为什么我的问题被否决了?问这样我就可以避免将来的错误。我想你想要的是
    grep-o
    而不是sed你不应该使用旧的和过时的backtics。像这样使用括号
    var=$(code)
    为什么我的问题被否决了?这样我就可以避免将来的错误了。谢谢。问题是我错过了捕获组之后的。*。其他人也指出了这一点,但我给了你复选标记,因为你得到了最完整的答案。谢谢。问题是我错过了捕获组之后的。*。其他人也指出了这一点,但我给了你复选标记,因为你得到了最完整的答案。这解决了它。谢谢。你不应该使用旧的和过时的背包。使用这样的括号
    var=$(code)
    @Jotne-yep我知道。有人说,OSX将不支持<代码>$()我在谷歌中没有发现任何东西表明它不工作。如果你不确定,张贴这两个,并说括号应该使用,如果它不工作,美国backtics。这修复了它。谢谢。你不应该使用旧的和过时的背包。使用这样的括号
    var=$(code)
    @Jotne-yep我知道。有人说,OSX将不支持<代码>$()我在谷歌中没有发现任何东西表明它不工作。如果你不确定,张贴这两个,并说括号应该使用,如果它不起作用,美国backtics。谢谢你,这是很高兴知道。但对于我目前的问题,我需要知道如何使用正则表达式获取文件名的特定位。在本例中,我只使用了文件名的第一个字母,因为它是一个非常简单的正则表达式,我想将问题归结为最简单的形式。但下一次我需要索引的子字符串时,我会使用这个。谢谢,知道这个很好。但对于我目前的问题,我需要知道如何使用正则表达式获取文件名的特定位。在本例中,我只使用了文件名的第一个字母,因为它是一个非常简单的正则表达式,我想将问题归结为最简单的形式。但下次我需要索引的子字符串时,我会使用这个。你不应该使用旧的和过时的backt