Расширение параметра не работает при использовании внутри Awk для одной из записей столбца
Система: Linux. Баш 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 ответа
Если я правильно понял ваше требование, не могли бы вы попробовать следующее.
val="_string"
awk -v value="$val" '{sub(".bam",value"&")} 1' Input_file
Краткое объяснение: -v value
означает передачу переменной оболочки с именем val
значение в переменную awk variable
Вот. Затем с помощью sub
функция awk
подставить строку .bam
со строковым значением вместе с .bam
значение, которое обозначается &
тоже. Тогда упомяну 1
означает печать отредактированной / нередактированной строки.
Почему попытка ОП не сработала: Уважаемый ОП. в awk
мы не можем передавать переменные оболочки напрямую, не упоминая их в awk
язык. Так что то, что вы пытаетесь, НЕ примет это как awk
переменная, а не будет принимать его как строку и печатать как есть. Я уже упоминал в своем объяснении выше, как определить переменные оболочки в awk
тоже.
ПРИМЕЧАНИЕ: если у вас есть несколько случаев .bam
тогда, пожалуйста, измените sub
в gsub
в приведенном выше коде. Также, если ваш Input_file является разделителем табуляции, используйте awk -F'\t'
в приведенном выше коде.
Обратите внимание, что расширение параметра, к которому вы применили $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
в части имени файла без расширения.
sed -i 's/\.bam/_string\.bam/g' myfile.txt
Это единственная строка с sed. Просто замените.bam на _string.bam
Вы можете попробовать этот способ с помощью awk:
awk -v a='_string' 'BEGIN{FS=OFS="."}{$1=$1 a}1' infile