Расширение параметра не работает при использовании внутри Awk для одной из записей столбца - PullRequest
0 голосов
/ 29 января 2019

Система: Linux.Bash 4.

У меня есть следующий файл, который будет считан в сценарий как переменная:

/path/sample_A.bam A 1
/path/sample_B.bam B 1
/path/sample_C1.bam C 1
/path/sample_C2.bam C 2 

Я хочу добавить «_string» в конце имени файлапервый столбец, но перед расширением (.bam).Это немного сложнее, потому что в начале имени содержится путь.

Желаемый вывод:

/path/sample_A_string.bam A 1
/path/sample_B_string.bam B 1
/path/sample_C1_string.bam C 1
/path/sample_C2_string.bam C 2 

Моя попытка: Я выполнил следующий скрипт (я запустил: bash script.sh):

List=${1};
awk -F'\t' -vOFS='\t' '{ $1 = "${1%.bam}" "_string.bam" }1' < ${List} ;

И его вывод был:

${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam

Проблема: Я следовал идее использования awk для этой замены, как в этой теме https://unix.stackexchange.com/questions/148114/how-to-add-words-to-an-existing-column,но расширение параметра $ {1% .bam} явно не распознается AWK, как я намереваюсь.Кто-нибудь знает правильный синтаксис для этой части кода?Эта часть должна была означать «все первые записи первого столбца, кроме последней части .bam».Я использовал $ {1% .bam}, потому что он работает в Bash, но AWK - это другой язык, и, вероятно, он отличается.Спасибо!

Ответы [ 4 ]

0 голосов
/ 29 января 2019

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

awk -v a='_string' 'BEGIN{FS=OFS="."}{$1=$1 a}1' infile
0 голосов
/ 29 января 2019

Обратите внимание, что расширение параметра, примененное к $1, не будет применено внутри awk, поскольку весь текст команды awk передается в '..', который отправляет содержимое буквально безприменяя разбор любой оболочки.Следовательно, строка "${1%.bam}" передается как есть в первый столбец.

Вы можете сделать это полностью в Awk

awk -F'\t' 'BEGIN { OFS = FS }{ n=split($1, arr, "."); $1 = arr[1]"_string."arr[2] }1'  file

Код в основном разделяет содержимое $1с разделителем . в массив arr в контексте Awk.Таким образом, часть строки до первого . сохраняется в arr[1], а последующие поля разбиения сохраняются в следующих индексах массива.Мы воссоздаем имя файла по вашему выбору, объединив записи массива с _string в части имени файла без расширения.

0 голосов
/ 29 января 2019
sed -i 's/\.bam/_string\.bam/g' myfile.txt

Это одна строка с sed.Просто замените .bam на _string.bam

0 голосов
/ 29 января 2019

Если я правильно понял ваше требование, не могли бы вы попробовать следующее.

val="_string"
awk -v value="$val" '{sub(".bam",value"&")} 1'  Input_file

Краткое объяснение: -v value означает передачу переменной оболочки с именем val значение для переменной awk variable здесь.Затем используя sub функцию awk для замены строки .bam на строковое значение наряду со значением .bam, которое также обозначается &.Тогда упоминание 1 означает печать отредактированной / нередактированной строки.

Почему попытка OP не сработала: Уважаемый OP.в awk мы не можем передавать переменные оболочки напрямую, не упоминая их на awk языке.Так что то, что вы пытаетесь, НЕ примет это как переменную awk, а не примет ее как строку и напечатает как есть.Я уже упоминал в своем объяснении выше, как определять переменные оболочки в awk.

ПРИМЕЧАНИЕ: Если у вас есть несколько вхождений .bam, тогда, пожалуйста,измените sub на gsub в приведенном выше коде.Также, если ваш Input_file является разделителем TAB, используйте awk -F'\t' в приведенном выше коде.

...