GNU/Linux 新手大家好。
我想在两列制表符分隔的文件中写入两个变量。在我的代码中,变量是$sample_name
和$file
。
我使用命令:
touch
创建文件并echo -e $sample_name $file | column -t >> $output_file
编写每一行。尽管这会产生一列文件。
有任何想法吗?
简化脚本:
touch $output_file
for file in $path/*.g.vcf; do
sample_name=`echo $file | grep -P 'HG(\d+)(?=.g)' -o`
echo -e $sample_name $file | column -t >> $output_file
done
预期输出(查看输出文件):
HG00321 ./.../HG00321/HG00321.g.vcf
HG00322 ./.../HG00322/HG00322.g.vcf
# and so on
答案1
您不需要使用column -t
(事实上,这将用空格扩展您的选项卡,以便无论宽度如何,列都能正确对齐)。只需使用printf
.并记住用双引号引用你的变量。例如
for file in "$path/"*.g.vcf; do
sample_name=$(echo "$file" | grep -P 'HG(\d+)(?=.g)' -o)
printf "%s\t%s\n" "$sample_name" "$file" >> "$output_file"
done
顺便说一句,不需要touch
文件来创建它。 >>
如果文件不存在,重定向将创建一个文件。
另外,您可以使用线<<<
来代替。例如echo
grep
sample_name=$(grep -oP 'HG(\d+)(?=.g)' <<< "$file")
这会将变量的内容(值)重定向$file
到 grep 命令中。无论哪种方式,实际上都没有任何显着的好处(除非变量包含改变echo
行为的值,例如-n
, -e
, -E
, 或一些反斜杠转义字符,例如\n
, \t
, \0nnn
,\xHH
等 - 请参阅help echo
bash。顺便说一句,这是为什么这些天printf
推荐echo
),但你可能会发现它更容易阅读。
答案2
看起来你想做的是这样的
for pathname in "$dirpath"/*.g.vcf; do
printf '%s\t%s\n' "$(basename "$pathname" .g.vcf)" "$pathname"
done >"$output_file"
这将循环匹配您的通配模式的路径名。对于每个路径名,使用basename
(也可以删除已知的文件名后缀)提取路径名的文件名部分.g.vcf
,并将其与完整路径名一起打印。
循环的输出被重定向到输出文件,如果该文件尚不存在,shell 将创建该文件;如果存在,则将截断(清空)该文件。
我更改了您使用的变量的名称path
,因为该名称与 shell 中同名的特殊(数组)变量发生冲突zsh
。我还在所有扩展周围添加了双引号,以确保我们可以处理所有可能的文件名。如果扩展未加引号,则文件名包含空格或通配字符会出现问题。
也可以看看:
在不使用该basename
实用程序的情况下,使用参数替换来修剪路径名中不需要的部分。此代码不使用任何外部实用程序:
for pathname in "$dirpath"/*.g.vcf; do
name=${pathname##*/}
printf '%s\t%s\n' "${name%.g.vcf}" "$pathname"
done >"$output_file"