假设我有文件: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.
在2个输入的简单情况下很难出错,但如果我这样做:
paste foo.tsv baz.tsv bar.tsv baz.tsv > foo_baz_bar_baz.tsv
有没有办法自动命名输出文件?如何让重定向操作员知道其输入?!
答案 0 :(得分:4)
您可以使用数组来跟踪所需的文件paste
:
files=("foo.tsv" "bar.tsv")
然后,paste "${files[@]}"
将展开为paste "foo.tsv" "bar.tsv"
。
最后,要重定向到名称基于参数的文件,您可以使用类似
的内容$ IFS=_
$ echo "${files[*]%.*}"
foo_bar
即,删除从最后一个点到阵列中所有元素的所有内容,然后将它们打印在一起,将内部字段分隔符设置为_
。
在Shell parameter expansion on arrays中描述了对数组中所有元素执行相同操作的内容,并使用${var[*]}
将它们打印在一起Bash Reference Manual → Special Parameters(对anishane的赞誉)评论中的建议。)
然后,将paste
命令重定向到使用此printf
创建的文件:
command > "$(echo "${files[*]%.*}".tsv)"
所有在一起:
files=("foo.tsv" "bar.tsv")
paste "${files[@]}" > "$(IFS=_; echo "${files[*]%.*}".tsv)"
答案 1 :(得分:3)
您还可以设置一个功能,为您完成大部分工作
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
也可以使用带空格的文件名。