bash 如何获取变量的第一个字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17723790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get first character of variable
提问by Martyn
I'm trying to get the first character of a variable, but I'm getting a Bad substitution error. Can anyone help me fix it?
我正在尝试获取变量的第一个字符,但出现了错误替换错误。任何人都可以帮我修复它吗?
code is:
代码是:
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
Am I doing something wrong or is there a better way of doing this?
我做错了什么还是有更好的方法来做到这一点?
-- EDIT --
- 编辑 -
As requested - here's some sample input which is stored in /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
回答by fedorqui 'SO stop harming'
To get the first character of a variable you need to say:
要获取变量的第一个字符,您需要说:
v="hello"
$ echo "${v:0:1}"
h
However, your code has a syntax error:
但是,您的代码有语法错误:
[ ! ${line:0:1} == "#"]
# ^-- missing space
So this can do the trick:
所以这可以解决问题:
$ a="123456"
$ [ ! "${a:0:1}" == "#" ] && echo "doesnt start with #"
doesnt start with #
$ a="#123456"
$ [ ! "${a:0:1}" == "#" ] && echo "doesnt start with #"
$
Also it can be done like this:
也可以这样做:
$ 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 #
Update
更新
Based on your update, this works to me:
根据您的更新,这对我有用:
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
回答by doubleDown
Adding the missing space (as suggested in fedorqui's answer;) ) works for me.
添加缺少的空间(如fedorqui 的回答中所建议的;) )对我有用。
An alternative method/syntax
替代方法/语法
Here's what I would do in Bash if I want to check the first character of a string
如果我想检查字符串的第一个字符,我会在 Bash 中执行以下操作
if [[ $line != "#"* ]]
On the right hand side of ==, the quoted part is treated literally whereas *is a wildcard for any sequence of character.
在 的右侧==,引用的部分按字面处理,而它*是任何字符序列的通配符。
For more information, see the last part of Conditional Constructsof Bash reference manual:
有关更多信息,请参阅Bash 参考手册的条件构造的最后一部分:
When the ‘==' and ‘!=' operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching
Checking that you're using the right shell
检查您是否使用了正确的外壳
If you are getting errors such as "Bad substitution error" and "[[: not found" (see comment) even though your syntax is fine (and works fine for others), it might indicate that you are using the wrong shell (i.e. not Bash).
如果您收到诸如“错误替换错误”和“ [[: 未找到”(请参阅注释)之类的错误,即使您的语法很好(并且对其他人也能正常工作),这可能表明您使用了错误的 shell(即不是 Bash)。
So to make sure you are using Bash to run the script, either
所以为了确保你使用 Bash 来运行脚本,要么
- make the script executable and use an appropriate shebang e.g.
#!/bin/bash - or execute it via
bash my_script
- 使脚本可执行并使用适当的shebang,例如
#!/bin/bash - 或通过执行它
bash my_script
Also note that shis not necessarily bash, sometimes it can be dash(e.g. in Ubuntu) or just plain ol' Bourne shell.
还要注意sh不一定是bash,有时它可以是破折号(例如在 Ubuntu 中)或只是普通的 ol' Bourne shell。
回答by jaypal singh
Try this:
尝试这个:
while IFS=$'\n' read line
do
if ! [ "${line:0:1}" = "#" ]; then
eval echo "$line"
eval createSymlink $line
fi
done < /some/file.txt
or you can use the following for your ifsyntax:
或者您可以使用以下if语法:
if [[ ! ${line:0:1} == "#" ]]; then
回答by Olivier Dulac
TIMTOWTDI ^^
蒂姆托迪^^
while IFS='' read -r line
do
case "${line}" in
"#"*) echo "${line}"
;;
*) createSymlink ${line}
;;
esac
done < /some/file.txt
Note: I dropped the eval, which could be needed in some (rare!) cases (and are dangerous usually).
注意:我放弃了 eval,它在某些(罕见!)情况下可能需要(并且通常很危险)。
Note2: I added a "safer" IFS & read (-r, raw) but you can revert to your own if it is better suited. Note that it still reads line by line.
注2:我添加了一个“更安全”的 IFS 并读取(-r,raw),但如果它更适合,您可以恢复为自己的。请注意,它仍然逐行读取。
Note3: I took the habit of using always ${var} instead of $var ... works for me (easy to find out vars in complex text, and easy to see where they begin and end at all times) but not necessary here.
注3:我习惯于总是使用 ${var} 而不是 $var ... 对我有用(很容易在复杂的文本中找出 vars,并且很容易看到它们的开始和结束位置)但在这里不是必需的.
Note4: you can also change the test to : *"#"*)if some of the (comments?) lines can have spaces or tabs before the '#' (and none of the symlink lines does contain a '#')
注意4:您还可以将测试更改为:*"#"*)如果某些(注释?)行在“#”之前可以有空格或制表符(并且没有任何符号链接行包含“#”)

