我有几十个文件,一半是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
你不需要for
循环。但是您确实需要确保两个数组的文件名顺序相同,因此您应该对它们进行排序。
您可以在find
和sort
中使用readarray
和选项,以便在文件名包含空格时不会遇到问题:
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