Forum Discussion

thecatfix's avatar
thecatfix
Dedicated Contributor
1 month ago

Amazing Command Line Workflow

This is my last post due to this janky editor. I had this in a nice format to read but due to the errors and time wasted its plain text

I spend most of my time in the terminal and struggle with quickly searching credentials or notes on the 1password application and will be building out out a new little command that outputs all fields from a selected item.

op item get "$(op item list --format json | jq -r '.[] | "\(.id) \(.title) [\(.vault.name)]"' | fzf | awk '{print $1}')" --format json | jq -r '.fields[] |

"\(.label): \(.value // .reference // "(empty)")"'

See a video of the workflow here -> https://screen.studio/share/0oSfsVhj

Hopefully u will have a laugh.

Thanks to the solution from mcky 

op item get $(op item list | fzf --header-lines=1 | awk '{print $1}')

Here is the final version of the command. It is a basically a poor man's TUI for 1password.

#!/usr/bin/env bash
set -euo pipefail

# Parse arguments
COPY_MODE=false
QUERY=""

while [[ $# -gt 0 ]]; do
  case $1 in
    -c|--copy)
      COPY_MODE=true
      shift
      ;;
    -h|--help)
      echo "Usage: opsearch [OPTIONS] [QUERY]"
      echo ""
      echo "Options:"
      echo "  -c, --copy     Copy selected field value to clipboard"
      echo "  -h, --help     Show this help message"
      echo ""
      echo "Examples:"
      echo "  opsearch                    # Interactive search"
      echo "  opsearch github             # Search for 'github' in titles"
      echo "  opsearch --copy             # Copy mode (interactive)"
      echo "  opsearch --copy aws         # Search 'aws' and copy result"
      exit 0
      ;;
    *)
      QUERY="$1"
      shift
      ;;
  esac
done

# Function to copy to clipboard based on OS
copy_to_clipboard() {
  local value="$1"
  if command -v pbcopy &> /dev/null; then
    # macOS
    echo -n "$value" | pbcopy
    echo "Copied to clipboard (macOS)"
  elif command -v xclip &> /dev/null; then
    # Linux with xclip
    echo -n "$value" | xclip -selection clipboard
    echo "Copied to clipboard (xclip)"
  elif command -v wl-copy &> /dev/null; then
    # Linux with wl-copy (Wayland)
    echo -n "$value" | wl-copy
    echo "Copied to clipboard (wl-copy)"
  else
    echo "Warning: No clipboard tool found (pbcopy, xclip, or wl-copy)" >&2
    echo "Value: $value"
    return 1
  fi
}

# Select item via fzf (with optional query filter)
if [[ -n "$QUERY" ]]; then
  # Search mode: filter items by query
  item_id=$(op item list --format json | jq -r --arg q "$QUERY" '.[] | select(.title | ascii_downcase | contains($q | ascii_downcase)) | "\(.id)\t\(.title)\t[\(.vault.name)]\tcreated: \(.created_at[:10])\tmodified: \(.updated_at[:10])"' |
  column -t -s $'\t' | fzf --header="Filter: $QUERY" | awk '{print $1}')
else
  # Interactive mode: show all items
  item_id=$(op item list --format json | jq -r '.[] | "\(.id)\t\(.title)\t[\(.vault.name)]\tcreated: \(.created_at[:10])\tmodified: \(.updated_at[:10])"' |
  column -t -s $'\t' | fzf | awk '{print $1}')
fi

if [[ -z "$item_id" ]]; then
  echo "No item selected." >&2
  exit 1
fi

# Fetch full item JSON once
item_json=$(op item get "$item_id" --format json)

vault=$(echo "$item_json" | jq -r '.vault.name')
item=$(echo "$item_json" | jq -r '.title')

# Display all fields
echo ""
echo "=== $item [vault: $vault] ==="
echo ""
echo "$item_json" | jq -r '.fields[] | "\(.label): \(.value // .reference // "(empty)")"'

# In copy mode, skip the field selection and use fzf for field
echo ""
if [[ "$COPY_MODE" == true ]]; then
  echo "=== Select field to copy ==="
else
  echo "=== Select a field for reference commands ==="
fi

# Pick a field via fzf
field=$(echo "$item_json" | jq -r '.fields[].label' | fzf)

if [[ -z "$field" ]]; then
  echo "No field selected." >&2
  exit 1
fi

# Get the field value for copying
field_value=$(echo "$item_json" | jq -r --arg f "$field" '.fields[] | select(.label == $f) | .value // .reference // empty')

# Copy mode: copy and exit
if [[ "$COPY_MODE" == true ]]; then
  if [[ -n "$field_value" && "$field_value" != "null" ]]; then
    echo ""
    copy_to_clipboard "$field_value"
    echo "Field: $field"
  else
    echo "Error: Field '$field' has no value to copy" >&2
    exit 1
  fi
  exit 0
fi

# Reference mode: show commands
ref="op://$vault/$item/$field"

echo ""
echo "Reference: $ref"
echo ""
echo "Commands:"
echo "  op read \"$ref\""
echo "  op run --env MYVAR=\"$ref\" -- <command>"
echo "  op inject -i <template> -o <output>  # use: {{ $ref }}"
echo ""
echo "Copy mode: opsearch --copy"

Now type opsearch and never context switch from the terminal.

4 Replies

  • thecatfix's avatar
    thecatfix
    Dedicated Contributor

    That is final version that adds

    1. Copy mode (-c or --copy) - Copies selected field to clipboard

    opsearch --copy # Interactive copy

    opsearch --copy github # Search + copy

    2. Quick lookup - Pass a query to filter items opsearch aws # Shows only items with "aws" in title

    3. Cross-platform clipboard support - Works on macOS (pbcopy), Linux X11 (xclip), and Wayland (wl-copy)

    4. Better UI - Clearer headers showing vault/item name

    Added openv helper to ~/.config/zsh/alias.zsh:

    openv "API Keys" npm run deploy # Load secrets and run command

    Usage examples:

    opsearch # Full interactive mode

    opsearch aws # Filter for AWS items

    opsearch -c # Copy mode (pick item → pick field → copied!)

    opsearch --copy github # Find github item, select field, auto-copy

  • 1P_Blake's avatar
    1P_Blake
    Icon for Community Manager rankCommunity Manager

    Hey thecatfix​! 👋

    Thanks so much for taking the time to share this, and sorry you ran into trouble with the editor! It's definitely frustrating when you've got something all nicely formatted and it just doesn't cooperate.

    I did my best to clean up the formatting on my end so it's easier to read, but I'll still pass that feedback along to our Community provider so we can look into what went wrong.

    • thecatfix's avatar
      thecatfix
      Dedicated Contributor

      DUDE NO! YOU NEED TO CHANGE THAT
      It is way to confusing.

      #!/usr/bin/env bash
      set -euo pipefail
      
      # Parse arguments
      COPY_MODE=false
      QUERY=""
      
      while [[ $# -gt 0 ]]; do
        case $1 in
          -c|--copy)
            COPY_MODE=true
            shift
            ;;
          -h|--help)
            echo "Usage: opsearch [OPTIONS] [QUERY]"
            echo ""
            echo "Options:"
            echo "  -c, --copy     Copy selected field value to clipboard"
            echo "  -h, --help     Show this help message"
            echo ""
            echo "Examples:"
            echo "  opsearch                    # Interactive search"
            echo "  opsearch github             # Search for 'github' in titles"
            echo "  opsearch --copy             # Copy mode (interactive)"
            echo "  opsearch --copy aws         # Search 'aws' and copy result"
            exit 0
            ;;
          *)
            QUERY="$1"
            shift
            ;;
        esac
      done
      
      # Function to copy to clipboard based on OS
      copy_to_clipboard() {
        local value="$1"
        if command -v pbcopy &> /dev/null; then
          # macOS
          echo -n "$value" | pbcopy
          echo "Copied to clipboard (macOS)"
        elif command -v xclip &> /dev/null; then
          # Linux with xclip
          echo -n "$value" | xclip -selection clipboard
          echo "Copied to clipboard (xclip)"
        elif command -v wl-copy &> /dev/null; then
          # Linux with wl-copy (Wayland)
          echo -n "$value" | wl-copy
          echo "Copied to clipboard (wl-copy)"
        else
          echo "Warning: No clipboard tool found (pbcopy, xclip, or wl-copy)" >&2
          echo "Value: $value"
          return 1
        fi
      }
      
      # Select item via fzf (with optional query filter)
      if [[ -n "$QUERY" ]]; then
        # Search mode: filter items by query
        item_id=$(op item list --format json | jq -r --arg q "$QUERY" '.[] | select(.title | ascii_downcase | contains($q | ascii_downcase)) | "\(.id)\t\(.title)\t[\(.vault.name)]\tcreated: \(.created_at[:10])\tmodified: \(.updated_at[:10])"' |
        column -t -s $'\t' | fzf --header="Filter: $QUERY" | awk '{print $1}')
      else
        # Interactive mode: show all items
        item_id=$(op item list --format json | jq -r '.[] | "\(.id)\t\(.title)\t[\(.vault.name)]\tcreated: \(.created_at[:10])\tmodified: \(.updated_at[:10])"' |
        column -t -s $'\t' | fzf | awk '{print $1}')
      fi
      
      if [[ -z "$item_id" ]]; then
        echo "No item selected." >&2
        exit 1
      fi
      
      # Fetch full item JSON once
      item_json=$(op item get "$item_id" --format json)
      
      vault=$(echo "$item_json" | jq -r '.vault.name')
      item=$(echo "$item_json" | jq -r '.title')
      
      # Display all fields
      echo ""
      echo "=== $item [vault: $vault] ==="
      echo ""
      echo "$item_json" | jq -r '.fields[] | "\(.label): \(.value // .reference // "(empty)")"'
      
      # In copy mode, skip the field selection and use fzf for field
      echo ""
      if [[ "$COPY_MODE" == true ]]; then
        echo "=== Select field to copy ==="
      else
        echo "=== Select a field for reference commands ==="
      fi
      
      # Pick a field via fzf
      field=$(echo "$item_json" | jq -r '.fields[].label' | fzf)
      
      if [[ -z "$field" ]]; then
        echo "No field selected." >&2
        exit 1
      fi
      
      # Get the field value for copying
      field_value=$(echo "$item_json" | jq -r --arg f "$field" '.fields[] | select(.label == $f) | .value // .reference // empty')
      
      # Copy mode: copy and exit
      if [[ "$COPY_MODE" == true ]]; then
        if [[ -n "$field_value" && "$field_value" != "null" ]]; then
          echo ""
          copy_to_clipboard "$field_value"
          echo "Field: $field"
        else
          echo "Error: Field '$field' has no value to copy" >&2
          exit 1
        fi
        exit 0
      fi
      
      # Reference mode: show commands
      ref="op://$vault/$item/$field"
      
      echo ""
      echo "Reference: $ref"
      echo ""
      echo "Commands:"
      echo "  op read \"$ref\""
      echo "  op run --env MYVAR=\"$ref\" -- <command>"
      echo "  op inject -i <template> -o <output>  # use: {{ $ref }}"
      echo ""
      echo "Copy mode: opsearch --copy"