如何使用unix命令合并不同文件夹中具有相似名称的多个文件?

如何使用unix命令合并不同文件夹中具有相似名称的多个文件?

我知道这个问题之前已经被问过并回答过,我已经尝试过代码,但没有得到正确的输出。

我有 2 个文件夹:vanila1 和 vanila2,每个文件夹都有 400 个名称相似的文件

ls vanila1
MB.2613.007_0021.ED4_KS1A29-7_338_all
MB.2613.007_0022.ED9_SD2A27-1_180_all
MB.2613.007_14.ED14_IA2A35-2_310_all

ls vanila2
MB.2613.007_0021.ED4_KS1A29-7_338_all
MB.2613.007_0022.ED9_SD2A27-1_180_all
MB.2613.007_14.ED14_IA2A35-2_310_all

我想合并具有相同名称的文件,我正在使用这个:

ls vanila1 | while read FILE; do
  cat vanila1/"$FILE" vanila2/"$FILE" >> all_combined/"$FILE"
done

我没有得到正确的输出,组合文件中的行数大于 file1 和 file 2 的总和。我做错了什么吗?

答案1

我有预感,您可能多次运行循环,并且由于您使用了>>重定向运算符,因此追加数据,你的结果文件每次都会增长。

相反(在这里我也避免使用ls,请参阅“为什么*不*解析`ls`?“出于原因):

for name in vanila1/*; do
    base_name=${name##*/}

    if [ -f "vanila2/$base_name" ]; then
        cat "$name" "vanila2/$base_name" >"all_combined/$base_name"
    else
        printf 'No file in vanila2 corresponds to "%s"\n' "$name" >&2
    fi
done

变量替换${name##*/}将路径名转换vanila1/MB.2613.007_0021.ED4_KS1A29-7_338_allMB.2613.007_0021.ED4_KS1A29-7_338_all,即它删除 之前的所有内容/,包括斜杠(这是路径名的文件名组成部分,或“基本名称”)。这可能会被替换$(basename "$name")

如果 中 存在vanila2与从 中获取的名称相对应的文件vanila1,则将这两个文件连接起来并放入该all_combined目录中。如果不是,则会出现有关此事实的诊断消息。

通过使用>而不是>>,任何现有的all_combined同名文件都将被替换而不是附加到。


如果你有其他文件或目录vanila1,那么您可能希望将循环中的模式修改vanila1/*为仅匹配您感兴趣的文件(例如vanila1/*_all或类似文件)。

答案2

那么,您在两个目录中有具有相同名称的文件,并且这两个文件都在哪里,您可以将它们连接起来?

for file in dir1/*; do
   otherfile="$(basename "$file")"
   if [[ -r dir2/"${otherfile}" ]]; then
       cat "$file" dir2/"$otherfile" >> combined/"$otherfile"
   fi
done

相关内容