Search code examples
bashzshmanjaro

How to fix sed tee awk syntax?


I'm a newbie on Manjaro Linux with zsh and using ranger as a file manager. It seems like the script was working before an update but not sure if it's at all related.

The script (shortcuts.sh) reads a file (.key_directories) that contains a list of paths to specific folders. Each line contains a few letters and a path to a directory, i.e. 2 columns:

examples:

md /run/media/
mov /run/media/movies
docs /run/media/docs

then adds a little bit of text which depends on which file the list will end up in. Either a text file (.shortcuts) which will be used as a list of aliases for bashrc and zshrc or a text file (shortcuts.conf) which will be used by ranger file manager as a list of path to different folders.

The script worked perfectly until it didn't. I'm not sure where the problem is.

Here is the full script shorcuts.sh:

#!/bin/bash

    # Shell rc file (i.e. bash vs. zsh, etc.)
    shellrc="$HOME/.zshrc"
    bshellrc="$HOME/.bashrc"

    # Config locations
    folders="$HOME/.config/ranger/.key_directories"
    configs="$HOME/.config/ranger/.key_files"

    # Output locations
    shell_shortcuts="$HOME/.shortcuts"
    ranger_shortcuts="$HOME/.config/ranger/shortcuts.conf"

    # Remove
    rm -f "$ranger_shortcuts" 2>/dev/null
    echo "alias \\" > "$shell_shortcuts"

    # Ensure text of argument 1 exists in the file argument 2
    ensure() { (grep "$1" "$2")>/dev/null 2>&1 || echo "$1" >> "$2" ;}

    ensure "source $shell_shortcuts" "$shellrc"
    ensure "source $shell_shortcuts" "$bshellrc"
    ensure "source $HOME/.config/ranger/shortcuts.conf" "$HOME/.config/ranger/rc.conf"

    # Format the `folders` file in the correct syntax and sent it to all three configs.
    sed "s/#.*$//;/^$/d" "$folders" | tee >(awk '{print $1"=\"cd "$2" && ls -a\" \\"}' >> "$shell_shortcuts") \
        | awk '{print "map g"$1" cd "$2"\nmap t"$1" tab_new "$2"\nmap m"$1" shell mv -v %s "$2"\nmap Y"$1" shell cp -rv %s "$2}' >> "$ranger_shortcuts"

    # Format the `configs` file in the correct syntax and sent it to both configs.
    sed "s/#.*$//;/^$/d"  "$configs" | tee >(awk '{print $1"=\"$EDITOR "$2"\" \\"}' >> "$shell_shortcuts") \
        | awk '{print "map "$1" shell $EDITOR "$2}' >> "$ranger_shortcuts"

Here is the .key_directories content:

# add here the path to your directories

md /run/media/
mov /run/media/movies
docs /run/media/docs

The error I get is:

shortcuts.sh: line 28: syntax error unexpected token `('
shortcuts.sh: line 28: sed "s/#.*$//;/^$/d" "$folders" | tee >(awk '{print $1"=\"cd "$2" && ls -a\" \\"}' >> "$shell_shortcuts") \

The script is supposed to use the text file .key_directories, ignore lines starting with # and empty lines. then take each line add the necessary text and create a new file with the result.

example: .key_directory

md /run/media

The script creates a text file .shortcuts with this content

alias \
md = cd /run/media

and then the script creates a text file shortcuts.conf with this content:

map gmd cd /run/media
map tmd tab_new /run/media
map mmd shell mv -v %s /run/media
map Ymd shell cp -rc %s /run/media

So far I've double checked if there was additional or missing spaces. Also tried swapping single quotes with double quotes and also removing them. But nothing really works and I spent already a few hours trying to understand how sed, tee and awk works seperatly and together with a bunch of examples but I still can't figure out why the script stopped working and how to fix.

If anybody could help, that would be awesome. Thank you in advance.

EDIT: bash version 5.0.7 / ZSH version 5.7.1


Solution

  • Looks like your script is being called with /bin/sh.
    Note: The #! line is used only if the script is called with absolute_or_relative_path/script_name.sh.
    If you call it as sh absolute_or_relative_path/script_name.sh, it will use /bin/sh as interpreter.