我需要检查一个文件是否包含特定的行。这个文件由某人持续写入,所以我将检查放在一个 while 循环中。
FILE="/Users/test/my.out"
STRING="MYNAME"
EXIT=1
while [ $EXIT -ne 0 ]; do
if [ -f $FILE ] ; then CHECK IF THE "STRING" IS IN THE FILE - IF YES echo "FOUND"; EXIT=0; fi
done
这个文件包含文本和多行内容。
我需要检查一个文件是否包含特定的行。这个文件由某人持续写入,所以我将检查放在一个 while 循环中。
FILE="/Users/test/my.out"
STRING="MYNAME"
EXIT=1
while [ $EXIT -ne 0 ]; do
if [ -f $FILE ] ; then CHECK IF THE "STRING" IS IN THE FILE - IF YES echo "FOUND"; EXIT=0; fi
done
这个文件包含文本和多行内容。
如果$FILE
包含文件名,$STRING
包含待搜索的字符串,则可以使用以下命令显示文件是否匹配:
if $FILE
包含文件名和 $STRING
包含要搜索的字符串,
那么您可以使用以下命令来显示文件是否匹配:
if [ ! -z $(grep "$STRING" "$FILE") ]; then echo "FOUND"; fi
grep "^$STRING"'$'
在这里可以考虑,但不够通用,因为STRING可能包含某些元素,这些元素可能被误认为是正则表达式。这也适用于所提出的解决方案。 - Holger Brandlfgrep
(grep -F
)... 这样,当搜索的字符串是文件行的子字符串时,这个检查会特别成功。 - x-yuri以下是 grep 命令的手册:
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. Also see the -s or --no-messages option.
-F, --fixed-strings
Interpret PATTERNS as fixed strings, not regular expressions.
-x, --line-regexp
Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
# Inline
grep -q -F "$STRING" "$FILE" && echo 'Found' || echo 'Not Found'
grep -q -F "$STRING" "$FILE" || echo 'Not Found'
# Multiline
if grep -q -F "$STRING" "$FILE"; then
echo 'Found'
else
echo 'Not Found'
fi
if ! grep -q -F "$STRING" "$FILE"; then
echo 'Not Found'
fi
如果需要检查整行,请使用-x
标志:
grep -q -x -F "$STRING" "$FILE" && echo 'Found' || echo 'Not Found'
当文件修改时间改变时,轮询并搜索字符串:
while :; do
a=$(stat -c%Y "$FILE") # GNU stat
[ "$b" != "$a" ] && b="$a" && \
grep -q "$STRING" "$FILE" && echo FOUND
sleep 1
done
stat -f%m
。如果要更严格地检查给定的行 $STRING 是否包含在文件 FILE 中,可以使用以下方法:
awk '$0 == "'${STRING}'"' $FILE
这特别涉及到我对 @fstab 的回答的担忧(适用于所有其他之前的回答):它检查整个行,而不仅仅是行内子字符串的存在(如上面使用 grep 解决方案所做的那样)。
循环可以按照其他答案所示进行。
尝试:
while : ;do
[[ -f "$FILE" ]] && grep -q "$STRING" "$FILE" && echo "FOUND" && break
done
while : ;do
[[ -f "$FILE" ]] && grep -q "$STRING" "$FILE" && echo "FOUND" && break
sleep 5
done
grep -q
:如果它找到了字符串,就不必读取整个文件:[[ -f "$f" ]] && grep -q "$str" "$f" && break
。 - glenn jackman将此评论转化为答案,因为它似乎符合我对原问题的理解和期望:
cat <<EOF | grep -Fx "${search_term}"
hello
world
EOF
hello
或 world
成功ello
或 worl
失败我需要在脚本中将ssh密钥添加到authorized_keys
文件中。我找到了两个选项(好的和丑陋的:)):
for f in "$tmp/keys/"*; do
line=`cat "$f"`
dst_line=`fgrep "$line" "$home/.ssh/authorized_keys" || true`
if [ "$line" != "$dst_line" ]; then
echo "$line" >> "$home/.ssh/authorized_keys"
fi
done
for f in "$tmp/keys/"*; do
cat "$f" >> "$home/.ssh/authorized_keys"
done
cat "$home/.ssh/authorized_keys" | sort | uniq > "$home/.ssh/authorized_keys.new"
chmod 0600 "$home/.ssh/authorized_keys.new"
chown "$user:" "$home/.ssh/authorized_keys.new"
mv "$home"/.ssh/authorized_keys.new \
"$home"/.ssh/authorized_keys
我以为用uniq
会更简洁,但结果并不是这样。而且需要调整权限...还有行的顺序会改变...看起来不太好。
comm
命令和-1
以及-2
开关:cat <<EOF > file.txt
line1
line2
line3
EOF
line_in_file=line1
[[ -n "$(comm -12 <(sort <<< "$line_in_file") <(sort "file.txt"))" ]] && echo 'line1 in file'
line_not_in_file=line4
[[ -n "$(comm -12 <(sort <<< "$line_not_in_file") <(sort "file.txt"))" ]] && echo 'line4 in file'
DESCRIPTION
Compare sorted files FILE1 and FILE2 line by line.
When FILE1 or FILE2 (not both) is -, read standard input.
With no options, produce three-column output. Column one contains lines unique to FILE1, column two contains lines unique to FILE2, and column three contains lines common to both files.
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
grep(1)
呢? - Martin Tournoij