13

Can someone help me convert this bash function to fish? It would also be nice if you could explain what these do like "${@%%.app}”, 's/ /.*/g’, "$@\” etc.

bid() {
    local shortname location

    # combine all args as regex
    # (and remove ".app" from the end if it exists due to autocomplete)
    shortname=$(echo "${@%%.app}"|sed 's/ /.*/g')
    # if the file is a full match in apps folder, roll with it
    if [ -d "/Applications/$shortname.app" ]; then
        location="/Applications/$shortname.app"
    else # otherwise, start searching
        location=$(mdfind -onlyin /Applications -onlyin ~/Applications -onlyin /Developer/Applications 'kMDItemKind==Application'|awk -F '/' -v re="$shortname" 'tolower($NF) ~ re {print $0}'|head -n1)
    fi
    # No results? Die.
    [[ -z $location || $location = "" ]] && echo "$1 not found, I quit" && return
    # Otherwise, find the bundleid using spotlight metadata
    bundleid=$(mdls -name kMDItemCFBundleIdentifier -r "$location")
    # return the result or an error message
    [[ -z $bundleid || $bundleid = "" ]] && echo "Error getting bundle ID for \"$@\"" || echo "$location: $bundleid”
}

Thanks very much in advance.

NorthCat
  • 9,643
  • 16
  • 47
  • 50
user14492
  • 2,116
  • 3
  • 25
  • 44

1 Answers1

60

Some notes on the differences:

  • setting variables
    • bash: var=value
    • fish: set var value
  • functions
    • bash
      funcName() {
          ...
      }
      
    • fish
      function funcName
          ...
      end
      
  • function arguments
    • bash: "$@", "$1", "$2", ...
    • fish: $argv, $argv[1], $argv[2], ...
  • function local variables
    • bash: local var
    • fish: set -l var
  • conditionals I
    • bash: [[ ... ]] and test ... and [ ... ]
    • fish: test ... and [ ... ], no [[ ... ]]
  • conditionals II
    • bash: if cond; then cmds; fi
    • fish: if cond; cmds; end
  • conditionals III
    • bash: cmd1 && cmd2
    • fish: cmd1; and cmd2
    • fish (as of fish 3.0): cmd1 && cmd2
  • command substitution
    • bash: output=$(pipeline)
    • fish: set output (pipeline)
  • process substitution
    • bash: join <(sort file1) <(sort file2)
    • fish: join (sort file1 | psub) (sort file2 | psub)

Documentation

faho
  • 14,470
  • 2
  • 37
  • 47
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • I still can’t figure out fish equivalent of `${@%%.app}`. I believe I know what it does i.e. return all the string in `$@` that contain .app at the end. So I would think it would be `$argv[**.app]` in fish but it gives _Could not expand_ error. – user14492 Apr 16 '15 at 14:23
  • 1
    `${@%%.app}` returns a list of all the positional parameters with any ".app" extensions removed. The fish equivalent is `for arg in $argv; set args $args (echo "$arg" | sed 's/.app$//'); end` – glenn jackman Apr 16 '15 at 15:47
  • I think you might have made a typo in `sed ’s/.app$//‘` with the $, in the comment above. Otherwise could you please explain why it’s there. – user14492 Apr 24 '15 at 17:27
  • for each element of the argv array, we're removing the ".app" extension, which appears at the end of the filename. The `$` is the regex "end-of-string" anchor. Actually I should have `sed 's/\.app$//'` escaping the dot. – glenn jackman Apr 24 '15 at 17:34
  • Thanks, without escaping the dot, it didn’t give expected results with $. – user14492 Apr 24 '15 at 17:47
  • You should start a new question and show what you're doing in fish. This does work: `set argv foo.bar.app qux baz.app; for arg in $argv; set args $args (echo "$arg" | sed 's/.app$//'); end; echo $args` outputs `foo.bar qux baz` – glenn jackman Apr 24 '15 at 18:07
  • [`bass`](https://github.com/edc/bass) "makes it easy to use utilities written for Bash in fish shell" – jitter Oct 01 '18 at 13:24