我有几十个文件,一半是TSV,一半是CSV。我要从它们各自的特定列中复制并将其粘贴到新的TSV文件中。我的代码如下:
paste <(cut -d , -f 3 -s file.csv) <(cut -f 2 -s file.tsv) > merged.tsv
TSV和CSV文件在文件名中共享ID。例如mary.tsv / mary.csv和joseph.tsv / joseph.csv。
如何通过将它们的文件名关联在一起来将mary.tsv和mary.csv替换为cut
命令?
到目前为止,我有:
tsvarray=(`find . -iname "*.tsv"`)
csvarray=(`find . -iname "*.csv"`)
然后我可以在for循环中执行以下代码?
paste <(cut -d , -f 3 -s $csvarray[@] <(cut -f 2 -s $tsvarray[@]) > merged.tsv
答案 0 :(得分:1)
您不需要for
循环。但是,您确实需要确保两个数组的文件名具有相同的顺序,因此您应该对它们进行排序。
您可以在readarray
和find
中使用sort
和选项,这样在文件名包含空格时不会出现问题:
readarray -d '' tsvarray < <(find . -iname '*.tsv' -print0 | sort -z)
readarray -d '' csvarray < <(find . -iname '*.csv' -print0 | sort -z)
然后,您需要使用正确的语法来引用带下标的数组。您需要在其周围放置{}
。然后,应再次引用它,以防止文件名包含空格时出现问题。
paste <(cut -d , -f 3 -s "${csvarray[@]}") <(cut -f 2 -s "${tsvarray[@]}") > merged.tsv
这还假设每个.csv
都有一个匹配的.tsv
,反之亦然。否则,数组将不对应。
如果要为每个csv / tsv对单独的合并文件,则 需要循环:
for ((i = 0; i < ${#tsvarray[@]}; i++)); do
paste <(cut -d , -f 3 -s "${csvarray[$i]}") <(cut -f 2 -s "${tsvarray[$i]}") > "${csvarray[$i]/.csv/.merged.csv}"
done