检查文件是否包含 bash 中的多行字符串
Check if a file contains a multi-line string in bash
背景
我正在编写一个函数来附加到我的 $HOME
目录中名为 .bash.local
的文件。
➡️ .bash.local
来自 .bash_profile
。
但是,我想有条件地附加到 .bash.local
当且仅当 文件 不 已经包含内容$BASH_CONFIGS
.
要记住的事情
我选择的操作系统是 MacOS Mojave
,因此某些版本的命令行应用程序会有所不同(例如 Mac 上的 grep
是 BSD grep
而不是 GNU grep
).
⚠️ append_to_bash_local()
append_to_bash_local() {
local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# If needed, add the necessary configs in the
# local shell configuration file.
if ! grep "^$BASH_CONFIGS" < "$LOCAL_BASH_CONFIG_FILE" &> /dev/null; then
# this block never runs, even if the contents of $BASH_CONFIG
# are NOT present in $HOME/.bash.local
fi
}
你很接近。无论如何,小修复:
- 使用零分隔
grep -Z
来匹配带有换行符的模式。如果你想到它,它有点 hacky,但每次都有效。
- 使用
-q
grep 使其静音。
- 并且不要将文件输入标准输入到 grep,只需告诉 grep 文件名即可。
- 检查文件是否存在
append_to_bash_local() {
local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
if [[ "$(uname)" == "Linux" ]]; then
if
# if a file does not exists
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ] ||
# if it doesn't have the content of BASH_CONFIGS
! grep -q -z "$BASH_CONFIGS" "$LOCAL_BASH_CONFIG_FILE"; then
echo appending
printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
else
echo not appending
fi
elif [[ "$(uname)" == "Darwin" ]]; then
if
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ] ||
! grep -q "$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(
less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' ''
); then
echo appending
printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
else
echo not appending
fi
fi
}
在 @kamil-cuk 的帮助下,我能够创建 append_to_bash_local()
的改进版本。
⚠️ 请注意,因为我在 MacOS Mojave
并且默认安装了 BSD-grep
和 BSD-sed
而 GNU-grep
和 GNU-sed
都没有安装, 使用 ASCII NUL 字符 截断换行符,我被迫寻找不同的解决方案。值得庆幸的是,@kamil-cuk 使用 tr
有一个 hacky 解决方案。
下面是append_to_bash_local()
的改进版本。
⚠️append_to_bash_local()
- 首先检查文件是否不存在
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ]
.
- 其次,使用
-q
和grep
使其静音。
- ➡️确保在
grep -q
前面放一个!
(不是)以确保输出的状态是反转的,因为我们正在检查文件不包含$BASH_CONFIGS
. 的内容
最后,使用 "$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' '')
以便 在 $BASH_CONFIGS
和 [] 中使用 ASCII NUL 字符 截断换行符=28=].
append_to_bash_local() {
local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# If needed, add the necessary configs in the
# local shell configuration file.
if [ ! -e "$LOCAL_BASH_CONFIG_FILE" ] || ! grep -q "$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' ''); then
printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
fi
}
背景
我正在编写一个函数来附加到我的 $HOME
目录中名为 .bash.local
的文件。
➡️ .bash.local
来自 .bash_profile
。
但是,我想有条件地附加到 .bash.local
当且仅当 文件 不 已经包含内容$BASH_CONFIGS
.
要记住的事情
我选择的操作系统是 MacOS Mojave
,因此某些版本的命令行应用程序会有所不同(例如 Mac 上的 grep
是 BSD grep
而不是 GNU grep
).
⚠️ append_to_bash_local()
append_to_bash_local() {
local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# If needed, add the necessary configs in the
# local shell configuration file.
if ! grep "^$BASH_CONFIGS" < "$LOCAL_BASH_CONFIG_FILE" &> /dev/null; then
# this block never runs, even if the contents of $BASH_CONFIG
# are NOT present in $HOME/.bash.local
fi
}
你很接近。无论如何,小修复:
- 使用零分隔
grep -Z
来匹配带有换行符的模式。如果你想到它,它有点 hacky,但每次都有效。 - 使用
-q
grep 使其静音。 - 并且不要将文件输入标准输入到 grep,只需告诉 grep 文件名即可。
- 检查文件是否存在
append_to_bash_local() {
local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
if [[ "$(uname)" == "Linux" ]]; then
if
# if a file does not exists
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ] ||
# if it doesn't have the content of BASH_CONFIGS
! grep -q -z "$BASH_CONFIGS" "$LOCAL_BASH_CONFIG_FILE"; then
echo appending
printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
else
echo not appending
fi
elif [[ "$(uname)" == "Darwin" ]]; then
if
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ] ||
! grep -q "$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(
less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' ''
); then
echo appending
printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
else
echo not appending
fi
fi
}
在 @kamil-cuk 的帮助下,我能够创建 append_to_bash_local()
的改进版本。
⚠️ 请注意,因为我在 MacOS Mojave
并且默认安装了 BSD-grep
和 BSD-sed
而 GNU-grep
和 GNU-sed
都没有安装, 使用 ASCII NUL 字符 截断换行符,我被迫寻找不同的解决方案。值得庆幸的是,@kamil-cuk 使用 tr
有一个 hacky 解决方案。
下面是append_to_bash_local()
的改进版本。
⚠️append_to_bash_local()
- 首先检查文件是否不存在
[ ! -e "$LOCAL_BASH_CONFIG_FILE" ]
. - 其次,使用
-q
和grep
使其静音。- ➡️确保在
grep -q
前面放一个!
(不是)以确保输出的状态是反转的,因为我们正在检查文件不包含$BASH_CONFIGS
. 的内容
- ➡️确保在
最后,使用
"$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' '')
以便 在$BASH_CONFIGS
和 [] 中使用 ASCII NUL 字符 截断换行符=28=].append_to_bash_local() { local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local declare -r BASH_CONFIGS=" # TOOL_NAME - TOOL_DESCRIPTION. # Add tool configurations here " # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # If needed, add the necessary configs in the # local shell configuration file. if [ ! -e "$LOCAL_BASH_CONFIG_FILE" ] || ! grep -q "$(<<<"$BASH_CONFIGS" tr '\n' '')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' ''); then printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE" fi }