11

我正在尝试获取变量的第一个字符,但出现了错误的替换错误。任何人都可以帮我解决它吗?

代码是:

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

4 回答 4

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
于 2013-07-18T12:44:54.863 回答
4

添加缺少的空间(如fedorqui 的回答中所建议的;) )对我有用。

另一种方法/语法

如果我想检查字符串的第一个字符,这就是我在 Bash 中要做的事情

if [[ $line != "#"* ]]

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

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

当使用 '==' 和 '!=' 运算符时,运算符右侧的字符串被认为是一个模式,并根据下面模式匹配中描述的规则进行匹配

检查您是否使用了正确的外壳

如果您收到诸如“错误替换错误”和“ [[: not found ”(参见注释)之类的错误,即使您的语法很好(并且对其他人也适用),这可能表明您使用了错误的 shell(即不是重击)。

因此,为了确保您使用 Bash 来运行脚本,要么

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

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

于 2013-07-18T13:20:45.503 回答
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
于 2013-07-18T12:57:49.033 回答
0

蒂姆托迪 ^^

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

注意:我放弃了 eval,在某些(罕见!)情况下可能需要它(并且通常很危险)。

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

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

注意4:您还可以将测试更改为:*"#"*)如果某些(注释?)行在“#”之前可以有空格或制表符(并且没有任何符号链接行包含“#”)

于 2018-02-09T16:58:07.353 回答