如何使用 bash 中的一行命令将文件名重定向到选项卡计数?

How could I redirect file name into counts by tab using one line commands in bash?

我有一些 fasta 格式的文件,想计算它们的读取次数,并希望输出文件名及其相应的计数。

输入文件名:

1.fa
2.fa
3.fa
...

我试过了:

for i in $(ls -t -v *.fa); do grep -c '>' $i > echo $i >> out.txt ; done

问题:

它给了我 out.txt 但是双文件名和它们的计数用 ':' 分隔。但是,我需要一个选项卡和唯一的文件名。

1.fa:7323580
1.fa:7323580
2.fa:5591179
2.fa:5591179
...

试试这个:

for i in $(ls -t -v *.fa)
do
    c=$(grep -c '>' $i | awk -F: '{print }')
    echo "$i: $c" >> out.txt
done

建议的解决方案

grep -c '>' *.fa | sed 's/:/'$'\t'/ > out.txt

$'\t\' 是一个叫做 ANSI C Quoting 的 Bash 主义。

分析出了什么问题

您的密码是:

for i in $(ls -t -v *.fa); do grep -c '>' $i > echo $i >> out.txt ; done

解析 ls 命令的输出不是一个好主意。但是,如果您的文件名表现良好(大致在 portable filename character set 中,即 [-A-Za-z._]),您就可以了。

不过,您的 grep 命令很混乱。它是:

grep -c '>' $i > echo $i >> out.txt

可以更清楚地写成:

grep -c '>' $i $i > echo >> out.txt

这意味着'在$i中计算包含>的行数,然后在$i中再次计算,并首先将输出发送到文件echo,然后附加到 out.txt。由于追加覆盖了重定向,因此文件 echo 为空。您得到输出中包含的文件名,因为有两个文件要搜索;只有一个文件,你也不会得到文件名。 (确保您获得具有常规文件名(不是 -c-lgrep 的一种方法是也扫描 /dev/nullgrep 的许多版本还提供明确获取名称的选项,但 POSIX 不强制要求一个。BSD grep 使用 -H;GNU grep 也是如此。)

所以,这就是为什么您在输出中得到双重文件名和条目的原因。