假设我有两个文件:foo.tsv
和bar.tsv
,其内容如下所示:
foo.tsv
1
2
3
4
5
bar.tsv
a
b
c
d
e
如果我运行paste foo.tsv bar.tsv > foo_bar.tsv
,我会得到:
foo_bar.tsv
1 a
2 b
3 c
4 d
5 e
虽然这很好,但我还是想自动命名为foo_bar.tsv
,以消除以误导性文件结束的可能性,例如,在输入错误的情况下。
比方说:
paste foo.tsv baz.tsv > foo_bar.tsv # foo_bar should have been foo_baz here.
在两个输入的简单情况下,很难搞错,但如果我这样做了:
paste foo.tsv baz.tsv bar.tsv baz.tsv > foo_baz_bar_baz.tsv
事情可能会变得一团糟。
是否有一种自动命名输出文件的方法?如何让重定向操作符知道它的输入?!
发布于 2016-08-11 08:51:48
您可以使用数组来跟踪要paste
在一起的文件:
files=("foo.tsv" "bar.tsv")
然后,paste "${files[@]}"
将扩展到paste "foo.tsv" "bar.tsv"
。
最后,要重定向到名称基于参数的文件,可以使用如下内容
$ IFS=_
$ echo "${files[*]%.*}"
foo_bar
也就是说,删除从最后一个点到数组中所有元素的所有内容,然后将它们一起打印,并将内部字段分隔符设置为_
。
在Shell parameter expansion on arrays中描述了对数组中的所有元素执行相同的操作,在Bash Reference Manual → Special Parameters中描述了使用${var[*]}
将它们打印在一起(对于注释中的建议,请称赞anishane )。
然后,将paste
命令重定向到使用此printf
创建的文件
command > "$(echo "${files[*]%.*}".tsv)"
总而言之:
files=("foo.tsv" "bar.tsv")
paste "${files[@]}" > "$(IFS=_; echo "${files[*]%.*}".tsv)"
发布于 2016-08-11 09:36:01
您还可以设置一个函数来为您完成大部分工作
pastefile(){
for i in "$@";do
newfile+="${i%.*}_"
done
ext="${1##*.}"
paste "$@" > "${newfile%_}.${ext}"
}
运行方式
$ pastefile foo.tsv bar.tsv
$ cat foo_bar.tsv
1 a
2 b
3 c
4 d
5 e
也可以使用带有空格的文件名。
https://stackoverflow.com/questions/38891399
复制