在列条目之一的 Awk 内部使用时,参数扩展不起作用
Parameter expansion not working when used inside Awk on one of the column entries
系统: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
我想在第一列文件名的末尾、扩展名 (.bam) 之前附加“_string”。由于在名称的开头包含路径,因此有点棘手。
期望输出:
/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
我的尝试:
我做了以下脚本 (I 运行: bash script.sh):
List=;
awk -F'\t' -vOFS='\t' '{ = "${1%.bam}" "_string.bam" }1' < ${List} ;
它的输出是:
${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam
问题:
我遵循了在这个线程 https://unix.stackexchange.com/questions/148114/how-to-add-words-to-an-existing-column 中使用 awk 进行此替换的想法,但是 ${1%.bam} 的参数扩展显然没有像我预期的那样被 AWK 识别。有人知道那部分代码的正确语法吗?该部分的意思是 "all the first entry of the first column, except the last part of .bam"。我使用 ${1%.bam} 是因为它适用于 Bash,但 AWK 是另一种语言,可能有所不同。谢谢!
如果我理解正确你的要求,请你试试看。
val="_string"
awk -v value="$val" '{sub(".bam",value"&")} 1' Input_file
简要说明: -v value
表示将shell变量名为val
的值传递给awk变量 variable
在这里。然后使用 awk
的 sub
函数将字符串 .bam
替换为字符串值以及 .bam
值,该值也由 &
表示。然后提到 1
意味着打印 edited/non-edtied 行。
为什么 OP 的尝试没有成功: 亲爱的,OP。在 awk
中,如果不在 awk
语言中提及它们,我们不能直接传递 shell 的变量。因此,您正在尝试的不会将其作为 awk
变量,而是将其作为字符串并按原样打印。我在上面的解释中也提到了如何在 awk
中定义 shell 变量。
注意: 如果 .bam
多次出现,请将 sub
更改为 gsub
在上面的代码中。另外,如果您的 Input_file 是 TAB 键,则在上面的代码中使用 awk -F'\t'
。
请注意,您在 </code> 上应用的参数扩展不会在 <code>awk
内作为整个命令应用
awk
命令的主体在 '..'
中传递,它按字面意思 发送内容 而不应用任何
shell 正在解析。因此,字符串 "${1%.bam}"
按原样传递到第一列。
您可以在 Awk
中完全做到这一点
awk -F'\t' 'BEGIN { OFS = FS }{ n=split(, arr, "."); = arr[1]"_string."arr[2] }1' file
代码基本上将</code>的内容用分隔符<code>.
分割成一个数组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="."}{= a}1' infile
系统: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
我想在第一列文件名的末尾、扩展名 (.bam) 之前附加“_string”。由于在名称的开头包含路径,因此有点棘手。
期望输出:
/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
我的尝试: 我做了以下脚本 (I 运行: bash script.sh):
List=;
awk -F'\t' -vOFS='\t' '{ = "${1%.bam}" "_string.bam" }1' < ${List} ;
它的输出是:
${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam
${1%.bam}_string.bam
问题: 我遵循了在这个线程 https://unix.stackexchange.com/questions/148114/how-to-add-words-to-an-existing-column 中使用 awk 进行此替换的想法,但是 ${1%.bam} 的参数扩展显然没有像我预期的那样被 AWK 识别。有人知道那部分代码的正确语法吗?该部分的意思是 "all the first entry of the first column, except the last part of .bam"。我使用 ${1%.bam} 是因为它适用于 Bash,但 AWK 是另一种语言,可能有所不同。谢谢!
如果我理解正确你的要求,请你试试看。
val="_string"
awk -v value="$val" '{sub(".bam",value"&")} 1' Input_file
简要说明: -v value
表示将shell变量名为val
的值传递给awk变量 variable
在这里。然后使用 awk
的 sub
函数将字符串 .bam
替换为字符串值以及 .bam
值,该值也由 &
表示。然后提到 1
意味着打印 edited/non-edtied 行。
为什么 OP 的尝试没有成功: 亲爱的,OP。在 awk
中,如果不在 awk
语言中提及它们,我们不能直接传递 shell 的变量。因此,您正在尝试的不会将其作为 awk
变量,而是将其作为字符串并按原样打印。我在上面的解释中也提到了如何在 awk
中定义 shell 变量。
注意: 如果 .bam
多次出现,请将 sub
更改为 gsub
在上面的代码中。另外,如果您的 Input_file 是 TAB 键,则在上面的代码中使用 awk -F'\t'
。
请注意,您在 </code> 上应用的参数扩展不会在 <code>awk
内作为整个命令应用
awk
命令的主体在 '..'
中传递,它按字面意思 发送内容 而不应用任何
shell 正在解析。因此,字符串 "${1%.bam}"
按原样传递到第一列。
您可以在 Awk
awk -F'\t' 'BEGIN { OFS = FS }{ n=split(, arr, "."); = arr[1]"_string."arr[2] }1' file
代码基本上将</code>的内容用分隔符<code>.
分割成一个数组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="."}{= a}1' infile