سؤال

I have a find script that automatically opens a file if just one file is found. The way I currently handle it is doing a word count on the number of lines of the search results. Is there an easier way to do this?

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

EDITED - here is the context of the whole script.

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"
هل كانت مفيدة؟

المحلول 3

Well, given that you are storing these results in the file $temp this is a little easier:

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

Instead of 'cat $temp' you can do '< $temp', but it might take away some readability if you are not very familiar with redirection 8)

نصائح أخرى

Unless I'm misunderstanding, the variable $temp contains one or more filenames, one per line, and if there is only one filename it should be edited?

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

If $temp is a file containing filenames:

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

Several of the results here will read through an entire file, whereas one can stop and have an answer after one line and one character:

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

For safely reading from find, if you have GNU find and bash as your shell, replace <file with < <(find ...) in the above. Even better, in that case, is to use NUL-delimited names, such that filenames with newlines (yes, they're legal) don't trip you up:

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

If you want to test whether the file is empty or not, test -s does that.

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

(A non-empty file by definition contains at least one line. You should find that wc -l agrees.)

If you genuinely want a line count of exactly one, then yes, it can be simplified substantially;

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

You can use arrays:

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

But you might have problems in case of filenames with whitespace, etc.

Still, something like this would be a native way

no this is the way, though you're making it over-complicated:

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

what's complicating it is:

  • useless use of cat,
  • unuseful use of xargs

and I'm not sure if you really want the editcat $temp`` which is editing the file at the content of $temp

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top