$ 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;
Вот так
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" #!/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
Вы можете попробовать этот 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
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