如何获得变量的第一个字符

时间:2013-07-18 12:43:13

标签: bash

我正在尝试获取变量的第一个字符,但是我遇到了错误的替换错误。任何人都可以帮我解决这个问题吗?

代码是:

while IFS=$'\n' read line
do
  if [ ! ${line:0:1} == "#"] # Error on this line
  then
    eval echo "$line"
    eval createSymlink $line
  fi
done < /some/file.txt

我做错了什么或者有更好的方法吗?

- 编辑 -

根据要求 - 这是一些存储在/some/file.txt

中的示例输入
$MOZ_HOME/mobile/android/chrome/content/browser.js
$MOZ_HOME/mobile/android/locales/en-US/chrome/browser.properties
$MOZ_HOME/mobile/android/components/ContentPermissionPrompt.js

4 个答案:

答案 0 :(得分:16)

要获取变量的第一个字符,您需要说:

v="hello"
$ echo "${v:0:1}"
h

但是,您的代码有语法错误:

[ ! ${line:0:1} == "#"]
#                     ^-- missing space

所以这可以解决问题:

$ a="123456"
$ [ ! "${a:0:1}" == "#" ] && echo "doesnt start with #"
doesnt start with #
$ a="#123456"
$ [ ! "${a:0:1}" == "#" ] && echo "doesnt start with #"
$ 

也可以这样做:

$ a="#123456"
$ [ "$(expr substr $a 1 1)" != "#" ] && echo "does not start with #"
$ 
$ a="123456"
$ [ "$(expr substr $a 1 1)" != "#" ] && echo "does not start with #"
does not start with #

更新

根据您的更新,这对我有用:

while IFS=$'\n' read line
do
  echo $line
  if [ ! "${line:0:1}" == "#" ] # Error on this line
  then
    eval echo "$line"
    eval createSymlink $line
  fi
done < file

答案 1 :(得分:4)

添加缺失的空间(如fedorqui's answer;)中所示)对我有用。

另一种方法/语法

如果我想检查字符串的第一个字符

,我会在Bash中做什么
if [[ $line != "#"* ]]

==的右侧,引用的部分按字面处理,而*是任何字符序列的通配符。

有关详细信息,请参阅Bash参考手册的Conditional Constructs的最后一部分:

  

当使用'=='和'!='运算符时,运算符右侧的字符串被视为一种模式,并根据Pattern Matching

中所述的规则进行匹配

检查您是否正在使用正确的shell

如果您收到错误,例如“错误的替代错误”和“ [[:找不到”(请参阅​​comment),即使您的语法是罚款(并且适用于其他人),它可能表明您使用的是错误的shell(即不是Bash)。

因此,要确保使用Bash运行脚本,

  • 使脚本可执行并使用适当的shebang,例如#!/bin/bash
  • 或通过bash my_script
  • 执行

另请注意, sh 不一定是 bash ,有时可以破折号(例如在Ubuntu中)或只是简单的'Bourne shell

答案 2 :(得分:2)

试试这个:

while IFS=$'\n' read line
do
  if ! [ "${line:0:1}" = "#" ]; then
    eval echo "$line"
    eval createSymlink $line
  fi
done < /some/file.txt

或者您可以使用以下if语法:

if [[ ! ${line:0:1} == "#" ]]; then

答案 3 :(得分:0)

TIMTOWTDI ^^

while IFS='' read -r line
do
  case "${line}" in
    "#"*)  echo "${line}"
    ;;
    *)     createSymlink ${line}
    ;;
  esac
done  < /some/file.txt

注意:我放弃了eval,这在一些(罕见!)情况下可能是必需的(通常是危险的)。

注2:我添加了一个更安全的&#34; IFS&amp;读取(-r,raw)但如果它更适合你可以恢复自己的状态。请注意,它仍然逐行读取。

注3:我习惯使用$ {var}而不是$ var ...对我有用(很容易找到复杂文本中的变量,并且很容易看到它们始终开始和结束的地方)但是这里没有必要。

注意4:如果某些(评论?)行在&#39;#&#39;之前可以有空格或标签,您也可以将测试更改为:*"#"*) (并且没有符号链接行确实包含&#39;#&#39;)