Заменить текст значениями

$ awk '/^Members/ { for (i=2; i<=NF; ++i) { sub(",$", "", $i); print $i } }' file
admin
Admin1
John
sam
dean

Здесь используется awkдля поиска любой строки, начинающейся со строки Members. Когда такая строка найдена, выполняется итерация по полям, разделенным пробелами -этой строки, начиная со второго поля и далее. В каждом поле удаляется завершающая запятая (, если она существует ), прежде чем оно будет напечатано на отдельной строке.

Перенаправить вывод в новый файл, если вы хотите его сохранить, используя

awk...as above... file >newfile

Использованиеsed:

$ sed -n '/^Members[[:blank:]]*/{ s///; s/,[[:blank:]]*/,/g; y/,/\n/; p; }' file
admin
Admin1
John
sam
dean

Это находит строки, начинающиеся со строки Members, а затем удаляет эту строку и все пробелы (, табуляции или пробелы ), следующие за ней.Затем он удаляет пробелы после любой запятой в оставшейся части строки и заменяет запятые на новые строки перед печатью результирующего списка.

С помощью GNU sedвы можете комбинировать

s/,[[:blank:]]*/,/g; y/,/\n/; p;

в

s/,[[:blank:]]*/\n/gp;
1
06.07.2018, 16:30
4 ответа

Вот так

awk '/^gene/{a[$1]=$2}/^COG/{c=$1;for(b=1;b<=NF;b++){c=sprintf("%s%s%c",c,a[$b],b==NF?"":" ")}print c}' file1 file2
COG0430 8 0
COG1949 578 3 0
COG5049 565 77 45 65
COG5104 67
  • /gene/{a[$1]=$2}ищет любые строки с «геном» в начале и создает массив элементов с ключом первого столбца (, например. «ген _1» )и значение следующего столбца (, например. «578»)
  • /^COG/ищет все строки с "COG" в начале...
  • c=$1устанавливает переменную c в первый столбец, например. "КОГ0430"
  • {c=sprintf("%s%s%c",c,a[$b],b==NF?"":" "продолжает добавлять элемент массива для каждого столбца в переменную c. Если это не последний столбец, добавьте разделитель пробелов.
  • print cзатем просто печатает полностью сформированную переменную "c"
0
28.01.2020, 00:33
#!/bin/bash
declare -A arr
readarray -t lines < "file1"

for line in "${lines[@]}"; do
   arr[${line%% *}]=${line#* }
done

readarray -t lines2 < "file2"

for line in "${lines2[@]}"; do
    echo -n "${line%% *} "
    for word in $line; do
        echo -n "${arr[$word]} "
    done
    echo
done

Не самый чистый баш, но работает. Также убедитесь, что у вас установлен bash >= 4.2

0
28.01.2020, 00:33

Вы можете попробовать этот awk

awk '
  NR == FNR {
    a[$1] = $2
    next
  }
  {
    for ( i = 2 ; i <= NF ; i++)
    $i = a[$i]
  }
1' file1 file2

или в одну строку

awk 'NR==FNR{a[$1]=$2;next}{for(i=2;i<=NF;i++)$i=a[$i]}1' file1 file2
0
28.01.2020, 00:33
 perl -ale '
    $h{$F[0]}=$F[1],next if @ARGV;
    my $k;
    print s/\H+/$k++ ? $h{$&} : $&/reg;
 ' file1 file2

° При чтении первого файла @ARGVсодержит второй аргумент и, следовательно, возвращает значение true.

° Заполнить хэш %hключами в виде имен генов и соответствующих значений из второго поля для каждой строки файла1.

° для второго файла @ARGV ничего не содержит и, следовательно, возвращает ложь. Последние две строки кода будут выполняться для каждой строки файла file2.

° Инициализировать переменную счетчика каждый раз, когда читается строка файла2. Тогда \H+должен соответствовать негоризонтальной последовательности символов пробела, iow, полю. А со 2-го числа запускаются сабвуферы от имени гена => номер гена.

Редактор sed с расширениями Gnu также может это делать:

 sed -Ee '
     # store file1 in hold
    /^C/!{H;1h;d;}

    # place a traveling marker \n\n at $2
    s/$/ /
    G
    s/(\S+\s+)/&\n\n/

    # effect gene name => gene number 
    :a
       s/\n\n(\S+)[ ]+((.*\n)?\1\s+([0-9]+))/ \4\n\n\2/
    ta

   # take away marker and hold portion
    s/\n\n.*//
 ' file1 file2 
0
28.01.2020, 00:33

Теги

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