4

我有一个查找脚本,如果只找到一个文件,它会自动打开一个文件。我目前处理它的方式是对搜​​索结果的行数进行字数统计。有没有更简单的方法来做到这一点?

if [ "$( cat "$temp" | wc -l | xargs echo )" == "1" ]; then
    edit `cat "$temp"`
fi

已编辑 - 这是整个脚本的上下文。

term="$1"
temp=".aafind.txt"

find src sql common -iname "*$term*" | grep -v 'src/.*lib'  >> "$temp"

if [ ! -s "$temp" ]; then
    echo "ø - including lib..." 1>&2
    find src sql common -iname "*$term*"  >> "$temp"
fi


if [ "$( cat "$temp" | wc -l | xargs echo )" == "1" ]; then
    # just open it in an editor
    edit `cat "$temp"`
else
    # format output
    term_regex=`echo "$term" | sed "s%\*%[^/]*%g" | sed "s%\?%[^/]%g" `
    cat "$temp" | sed -E 's%//+%/%' | grep --color -E -i "$term_regex|$"
fi

rm "$temp"
4

6 回答 6

7

除非我有误解,否则变量$temp包含一个或多个文件名,每行一个,如果只有一个文件名,应该编辑它?

[ $(wc -l <<< "$temp") = "1" ] && edit "$temp"

如果$temp是包含文件名的文件:

[ $(wc -l < "$temp") = "1" ] && edit "$(cat "$temp")"
于 2014-01-29T22:51:26.777 回答
3

这里的几个结果将读取整个文件,而一个可以停止并在一行和一个字符后得到答案:

if { IFS='' read -r result && ! read -n 1 _; } <file; then
  echo "Exactly one line: $result"
else
  echo "Either no valid content at all, or more than one line"
fi

为了安全地阅读find,如果你有 GNU find 和 bash 作为你的 shell,请在上面替换<file< <(find ...)。更好的是,在这种情况下,使用 NUL 分隔的名称,这样带有换行符的文件名(是的,它们是合法的)不会让你失望:

if { IFS='' read -r -d '' result && ! read -r -d '' -n 1 _; } \
        < <(find ... -print0); then
    printf 'Exactly one file: %q\n' "$result"
else
    echo "Either no results, or more than one"
fi
于 2014-01-29T22:52:01.737 回答
2

如果要测试文件是否为空,请test -s执行此操作。

if [ -s "$temp" ]; then
    edit `cat "$temp"`
fi

(根据定义,一个非空文件至少包含一行。您应该会发现它wc -l同意。)

如果你真的想要一个正好为 1 的行数,那么是的,它可以大大简化;

if [ $( wc -l <"$temp" ) = 1 ]; then
    edit `cat "$temp"`
fi
于 2014-01-29T22:47:56.857 回答
1

您可以使用数组:

 x=($(find . -type f))
 [ "${#x[*]}" -eq 1 ] && echo "just one || echo "many"

但是如果文件名带有空格等,您可能会遇到问题。

不过,这样的事情将是一种原生方式

于 2014-01-29T22:49:34.293 回答
1

不,这是这种方式,尽管你让它变得过于复杂:

if [ "`wc -l $temp | cut -d' ' -f1`" = "1" ]; then 
    edit "$temp";
fi

复杂的是:

  • 无用的使用cat
  • 无用的使用xargs

而且我不确定您是否真的想要editcat $temp``,它正在以 $temp 的内容编辑文件

于 2014-01-29T22:50:19.163 回答
1

好吧,鉴于您将这些结果存储在文件 $temp 中,这更容易一些:

[ "$( wc -l < $temp )" -eq 1 ] && edit "$( cat $temp )"

你可以用 '< $temp' 代替 'cat $temp',但如果你对重定向不是很熟悉,它可能会降低一些可读性 8)

于 2014-01-29T22:52:12.820 回答