sed: -e выражение #1, символ 37: неопределенная команда `s'

#!/bin/sh

junkdir="$HOME/.junk"
do_list=false
do_purge=false

while getopts 'lp' opt; do
    case "$opt" in
        l) do_list=true  ;;
        p) do_purge=true ;;
        *)
            printf 'Usage: %s [-l|-p] [ name... ]\n' "$0" >&2
            exit 1
    esac
done

shift "$(( OPTIND - 1 ))"

if [ ! -d "$junkdir" ] && ! "$do_purge"; then
    printf '%s: Missing junk directory "%s"\n' "$0" "$junkdir" >&2
    printf '%s: Re-run with -p to create it\n' "$0" >&2
    exit 1
fi

if "$do_list"; then
    printf 'Current junk in "%s":\n' "$junkdir"
    ls -l "$junkdir"
fi

if "$do_purge"; then
    printf 'Emptying junk directory "%s"\n' "$junkdir"
    rm -rf "$junkdir"
    mkdir "$junkdir"
fi

if [ "$#" -eq 0 ]; then
    exit
fi

echo 'Junking the following things:'
printf '%s\n' "$@"

mv "$@" "$junkdir"

Этот сценарий реализует то, что вы пытаетесь сделать. Он использует getoptsдля разбора флагов командной строки -lи/или -p.

Я устанавливаю do_listи do_purgeв цикле while, который анализирует параметр командной строки, потому что я хочу контролировать порядок, в котором lsи rmрасположены ниже. Если пользователь использует -lpили -pl, я хочу, чтобы они увидели содержимое каталога нежелательной почты до того, как он будет удален.

Удаление ненужного каталога с помощью -pтакже создает его заново. Я делаю это с помощью rm -rf, за которым следует mkdirдля простоты.

После цикла синтаксического анализа командной строки я корректирую позиционные параметры так, чтобы они содержали только не -аргументы опций (имена файлов и/или каталогов ).

Если нет позиционных аргументов,($#равно нулю ), я не пытаюсь запустить mv, чтобы переместить файлы в ненужный каталог.

2
28.08.2019, 18:42
1 ответ

Если у вас есть несколько совпадений, grep -oвыдаст несколько строк вывода. И символы новой строки заканчиваются sedкомандами:

$ echo abcabbcd | grep -o 'ab*'
ab
abb

$ repl=$(echo abcabcd | grep -o 'ab*')
$ sed -e "s/foo/$repl/"
sed: -e expression #1, char 8: unterminated `s' command

Кроме того, [^</title>]+означает «один или несколько символов, которые не являются ни одним из ^, <, /, t, i, l, eили >. ]». Возможно, это не то, чего вы на самом деле хотите:

$ echo '<title>abcdefgh</title>' | grep -Po '<title>\K[^</title>]+'
abcd

Вы можете использовать эквивалент, если разделитель состоит из одного символа, например. "[^"]*"нормально. Но здесь что-то вроде <title>\K.*?(?=</title>)'может подойти лучше:

$ echo '<title>abcdefgh</title> <title>foobar</title>' | grep -Po '<title>\K.*?(?=</title>)'
abcdefgh
foobar

(Хотя я бы избегал таких уловок, как \Kи просмотр вперед, и вместо этого использовал более простую perl -lne 'print $1 if m,<title>(.*?)</title>,'или пост--обработку вывода, но это мое предпочтение.)

3
27.01.2020, 22:02

Теги

Похожие вопросы