Нужна помощь с awk или sed

В то время как $1и его друзья работают достаточно хорошо для сценариев с фиксированным набором аргументов, они не очень хорошо работают для сценариев с динамическими аргументами. Для этого вы хотите использовать цикл и структуру case :

.
REMOVE=
for arg in "$@"; do
    case "$arg" in
        --remove)
            REMOVE=1
            ;;
        *)
            if [ ! -z "$REMOVE" ]; then
                # whatever you need to do to remove
            else
                # whatever you need to do if you do not want to remove
            fi
            ;;
    esac
done

Это хорошо работает, если вы задокументируете, что --remove применяется только к аргументам, которые идут после него; это позволит вам иметь смешанную командную строку, где удаление применяется к одним аргументам, но не к другим:

script.sh arg1 arg2 --remove arg3

в приведенном выше примере --removeотносится к arg3, но не к arg1 или arg2. Вы также можете добавить поддержку параметра командной строки --noremoveв структуру вашего кейса:

case "$arg" in
    --noremove)
        REMOVE=
        ;;
    --remove)
        #... rest of the case remains as is from before
esac

что позволило бы сделать что-то подобное:

script.sh --remove arg1 --noremove arg2 --remove arg3

в этом примере параметр --removeприменяется к arg1 и arg3, но не к arg2.

Наконец, если вы хотите, чтобы ваш --removeприменялся к любому аргументу, независимо от того, где он появляется в командной строке, то, вероятно, самый простой способ двигаться вперед — это использоватьgetopt(1):

# reorder the command line so that option arguments come first
# and non-option arguments come second, separated by "--"
PARSED=$(getopt -o '' --long remove -n scriptname.sh -- "$@")
# overwrite $@ with the contents of the newly created $PARSED
# Note the quotes; they are essential
eval set -- "$PARSED"

REMOVE=

while true; do
    case "$1" in
        --remove)
            REMOVE=1
            shift
            ;;
        --)
            shift; break;
    esac
done

for arg in "$@"; do
    if [ ! -z "$REMOVE" ]; then
        # whatever you need to do to remove
    else
        # the other thing
    fi
done

Аргумент -oдля getoptпринимает короткие параметры, так что вы можете использовать -rвместо --remove, если хотите. Getopt также имеет несколько дополнительных опций, когда вы хотите, чтобы опции (опционально )имели аргументы и т. д., и позволяет бесплатно выводить основные данные об использовании, когда пользователи предоставляют опции, которые не распознаются вашим скриптом. Есть пример, поставляемый с GNU getopt, который показывает все возможности; в Debian (и его производных )вы можете найти его как/usr/share/doc/util-linux/getopt-parse.bash

-3
08.09.2020, 21:25
3 ответа

команда

awk -F "," '{for(i=1;i<=NF;i++){sub(/.*:/,"",$i);print $i}}' filename|sed -r "s/^\s+//g"| sed "s/[u'}]//g"| awk 'ORS="," {print $0}'|sed "s/,$//g"

выход

4.1.4.339,U32 v2.34 (04/08/2020),2.65,example,2.18 Jn 22 2020,20.14.62,HPD5,14.26.1040,12.24.1000,0.2.2.0,14.26.1040
0
18.03.2021, 23:06

Вы можете сделать это полностью в sed, но, как видите, sedне является идеальным инструментом для этого конкретного случая использования, если только вы не любите писать очень длинные sedкоманды. Я настоятельно рекомендую вместо этого использовать awk.

$ sed -e 's/[{}]//g; s/, /,/g; s/: /\n/g' file | \ 
sed -e "s/^u//g; s/'//g; s/,/\n/g" | sed -n 'g;n;p' | \
sed -n 's/.*/&,/;H;$x;$s/,\n/, /g;$s/\n\(.*\)/\1/;$s/\(.*\),/\1/;$p'
4.1.4.339, U32 v2.34 (04/08/2020), 2.65, example, 2.18 Jun 22 2020, 20.14.62, HPD5, 14.26.1040, 12.24.1000, 0.2.2.0, 14.26.1040
0
18.03.2021, 23:06

Как предполагает стилдрайвер:

line="{'REST_SPS': u'4.1.4.339', 'REST_ROM': u'U32 v2.34 (04/08/2020)', 'REST_SMART': u'2.65', 'Server': 'example', 'REST_ILO': u'2.18 Jun 22 2020', 'REST_1G': u'20.14.62', 'REST_DISK': u'HPD5', 'REST_10G_2': u'14.26.1040', 'REST_IB': u'12.24.1000', 'REST_IE': u'0.2.2.0', 'REST_10G_1': u'14.26.1040'}"

echo "$line" | python3 -c '
import sys
line = sys.stdin.readline()
d = eval(line)
keys = ["REST_SPS", "REST_ROM", "REST_SMART", "Server", "REST_ILO", "REST_1G", "REST_DISK", "REST_10G_2", "REST_IB", "REST_IE", "REST_10G_1"]
print(", ".join([d[k] for k in keys]))
'
4.1.4.339, U32 v2.34 (04/08/2020), 2.65, example, 2.18 Jun 22 2020, 20.14.62, HPD5, 14.26.1040, 12.24.1000, 0.2.2.0, 14.26.1040

На самом деле я не специалист по питонам, так что, вероятно, нужно немного улучшить.

И если вы читаете строки из файла, вам не нужно вызывать python один раз для каждой строки :выполнять обработку в python.

1
18.03.2021, 23:06

Теги

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