我有兴趣根据数字将许多文件连接在一起,并删除第一行。
例如chr1_smallfiles 然后是 chr2_smallfiles 然后是 chr3_smallfiles.... 等等(每个都没有标题)
请注意 chr10_smallfiles
需要在 chr9_smallfiles
之后——也就是说,这需要是数字排序顺序。
当将 awk 和 ls -v1 这两个命令分开时,每个命令都能正常工作,但是当把它们放在一起时,它就不起作用了。请帮忙谢谢!
awk 'FNR>1' | ls -v1 chr*_smallfiles > bigfile
最佳答案
问题在于您尝试将文件列表传递给 awk 的方式。目前,您正在将 awk 的输出通过管道传输到 ls,这是没有意义的。
请记住,正如评论中提到的,ls 是一个用于交互使用的工具,通常不应解析其输出。
如果排序不是问题,您可以使用:
awk 'FNR > 1' chr*_smallfiles > bigfile
shell 会将 glob chr*_smallfiles
扩展为一个文件列表,这些文件作为参数传递给 awk。对于每个文件名参数,将打印除第一行以外的所有内容。
既然您要对文件进行排序,事情就没那么简单了。如果您确定所有文件都存在,只需将原始命令中的 chr*_smallfiles
替换为 chr{1..99}_smallfiles
。
使用一些特定于 Bash 和 GNU 的排序功能,您还可以像这样实现排序:
printf '%s\0' chr*_smallfiles | sort -z -n -k1.4 | xargs -0 awk 'FNR > 1' > bigfile
printf '%s\0'
打印每个文件名后跟一个空字节sort -z
对以空字节分隔的记录进行排序-n -k1.4
从第 4 个字符(文件名的数字部分)开始进行数字排序xargs -0
将排序后的、以 null 分隔的输出作为参数传递给 awk
否则,如果您想按数字顺序遍历文件,并且不确定是否所有文件都存在,那么您可以使用 shell 循环(尽管它会比单个 awk 调用慢得多) :
for file in chr{1..99}_smallfiles; do # 99 is the maximum file number
[ -f "$file" ] || continue # skip missing files
awk 'FNR > 1' "$file"
done > bigfile
关于bash - 根据 awk w/o header 中的名称子字符串的数字排序连接文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49280905/