Bash脚本:如果该行尚不存在,则仅对〜/ .bash_profile回显一行

时间:2010-12-18 19:03:25

标签: bash shell scripting sed grep

我写了bash git-install script。最后,我做了:

echo "Edit ~/.bash_profile to load ~/.git-completioin.bash on Terminal launch"
echo "source ~/.git-completion.bash" >> ~/.bash_profile

问题是,如果多次运行脚本,最后会多次将此行附加到〜/ .bash_profile。如何使用grepsed(或您可能推荐的其他选项)使用bash脚本来仅添加文件中尚不存在的行。另外,如果该文件存在且~/.profile不存在,我想将该行添加到~/.bash_profile,否则只需将其添加到~/.bash_profile

4 个答案:

答案 0 :(得分:11)

这样的事情应该这样做:

LINE_TO_ADD=". ~/.git-completion.bash"

check_if_line_exists()
{
    # grep wont care if one or both files dont exist.
    grep -qsFx "$LINE_TO_ADD" ~/.profile ~/.bash_profile
}

add_line_to_profile()
{
    profile=~/.profile
    [ -w "$profile" ] || profile=~/.bash_profile
    printf "%s\n" "$LINE_TO_ADD" >> "$profile"
}

check_if_line_exists || add_line_to_profile

几点说明:

  • 我使用.命令代替source,因为source是一种基础,但非bash shell可能会使用.profile。命令source ....profile
  • 中出错
  • 我使用了printf而不是echo,因为它更具可移植性,并且不会像bash echo那样搞乱反斜杠转义的字符。
  • 尝试对非明显的失败更加强大。在这种情况下,在尝试写入之前,请确保.profile存在且可写
  • 我使用grep -Fx来搜索字符串。 -F表示固定字符串,因此搜索字符串中的特殊字符不需要转义,-x表示仅匹配整行。 -qs是常见的grep语法,用于检查字符串的存在而不显示它。
  • 这是概念证明。我实际上并没有这样做。我很糟糕,但是星期天早上我想出去玩。

答案 1 :(得分:6)

if [[ ! -s "$HOME/.bash_profile" && -s "$HOME/.profile" ]] ; then
  profile_file="$HOME/.profile"
else
  profile_file="$HOME/.bash_profile"
fi

if ! grep -q 'git-completion.bash' "${profile_file}" ; then
  echo "Editing ${profile_file} to load ~/.git-completioin.bash on Terminal launch"
  echo "source \"$HOME/.git-completion.bash\"" >> "${profile_file}"
fi

答案 2 :(得分:2)

怎么样:

grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile || echo "source ~/.git-completion.bash" >> ~/.bash_profile

或以更明确(和可读)的形式:

if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then
    echo "Updating" ~/.bash_profile

    echo "source ~/.git-completion.bash" >> ~/.bash_profile
fi

编辑:

你应该在你的单行之前添加一个额外的换行符,以防万一~/.bash_profile没有结束:

if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then
    echo "Updating" ~/.bash_profile

    echo >> ~/.bash_profile   
    echo "source ~/.git-completion.bash" >> ~/.bash_profile
fi

编辑2:

这样修改起来更容易一些,也更容易移植:

LINE='source ~/.git-completion.bash'

if ! grep -Fx "$LINE" ~/.bash_profile >/dev/null 2>/dev/null; then
    echo "Updating" ~/.bash_profile

    echo >> ~/.bash_profile   
    echo "$LINE" >> ~/.bash_profile
fi

-F-x选项由POSIX指定,并在其他几个答案和评论中提出。

答案 3 :(得分:1)

# Decide which profile to add to
PROFILE=~/.bash_profile
if ! [ -e "$PROFILE" ] && [ -e ~/.profile ]; then
    PROFILE=~/.profile
fi

# Add to profile if it doesn't appear to be there already. Err on the side of
# not adding it, in case user has made edits to their profile.
if ! grep -s 'git-completion\.bash' "$PROFILE"; then
    echo "Editing $PROFILE to load ~/.git-completion.bash on Terminal launch"
    echo "source ~/.git-completion.bash" >> "$PROFILE"
fi