Как правильно разобрать этот сценарий в простом скрипте bash? - PullRequest
1 голос
/ 23 марта 2011

У меня есть файл, в котором каждая пара ключ-значение занимает новую строку. Существует возможность иметь несколько значений для каждого ключа. Я хочу вернуть список всех пар, у которых есть «специальный ключ», где «специальный» определяется как некоторая функция.

Например, если «специальный» определяется как ключ, который где-то имеет значение 100

A 100
B 400
A hello
B world
C 100

Я бы вернулся

A 100
A hello
C 100

Как это сделать в bash?

Ответы [ 5 ]

1 голос
/ 24 марта 2011
awk -v special="100" '$2==special{a[$1]}($1 in a)' file
1 голос
/ 23 марта 2011

***** скрипт *****

#!/bin/bash

grep " $1" data.txt | cut -d ' ' -f1 | grep -f /dev/fd/0 data.txt

результат:

./test.sh 100

A 100
A hello
C 100

***** inline *****

первый grep должен содержать 'special', которому предшествует пробел '':

grep " 100" data.txt | cut -d ' ' -f1 | grep -f /dev/fd/0 data.txt

A 100
A hello
C 100
1 голос
/ 23 марта 2011

Это также будет работать:

id=`grep "\<$special\>$" yourfile | sed -e "s/$special//"`
[ -z "$id" ] || grep "^$id" yourfile

Возвращает:

Если special=100

A 100
A hello
C 100

Если special="hello"

A 100
A hello

Если special="A"

(nothing)

Если special="ello"

(nothing)

Примечания

  • отбросить \<\>, если вы хотите частичное совпадение
  • добавить | uniq в конце, если есть возможность нескольких входов одной пары (A 100, A 100, ...), но вы не хотите, чтобы это было в ваших выходных данных.
1 голос
/ 23 марта 2011
#!/bin/bash

special=100    

awk -v s=$special '
{
  a[$1,$2]
  if($2 ~ s)
    k[$1]
}

END
{
  for(key in k)
    for(pair in a)
    {
      split(pair,b,SUBSEP)
        if(b[1] == key)
          print b[1],b[2]
    }
}' ./infile

Подтверждение концепции

$ special=100; echo -e "A 100\nB 400\nA hello\nB world\nC 100" | awk -v s=$special '{a[$1,$2];if($2 ~ s)k[$1]}END{for(key in k)for(pair in a){split(pair,b,SUBSEP); if(b[1] == key)print b[1],b[2]}}'
A hello
A 100
C 100
0 голосов
/ 23 марта 2011

Уф!Мой удар был невероятно ржавым!Надеюсь, это поможет:

FILE=$1
IFS=$'\n' # Internal File Sep, so as to avoid splitting in whitespaces
FIND="100"
KEEP=""

for line in `cat $FILE`; do
    key=`echo $line | cut -d \  -f1`;
    value=`echo $line | cut -d \  -f2`;

    echo "$key = $value"

    if [ "$value" == "$FIND" ]; then
            KEEP="$key $KEEP"
    fi
done

echo "Keys to keep: $KEEP"

# You can now do whatever you want with those keys.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...