如何合并文本文件 - Bash 脚本

如何合并文本文件 - Bash 脚本

我想编写一个脚本,将文本文件作为参数并合并它们。

  • 所有文件都由用空行分隔的分组行组成。
  • 该脚本可以接受 2 个以上的参数
  • 文件可以包含更多组
  • 如果文件有不同的组数,当一个文件中的组结束时,另一个文件中剩余的组应按如下顺序依次添加:111-211-121-122-221-222-223-131-132-133-231-241-251-261-271

    我想将文件合并到标准输出,输出应该是“第一个文件的第一组,第二个文件的第一组,然后第一个文件的第二组......”

    假设文件中的行格式为“文件编号_组编号_行编号”,如下所示:

01_01_01

01_02_01
01_02_02
01_02_03

01_03_01
02_01_01
02_01_02

02_02_01

02_03_01
02_03_02

那么输出应该是:

01_01_01
02_01_01
01_02_01
01_02_02
01_02_03
02_02_01
01_03_01
02_03_01
02_03_02

我尝试使用paste但遇到了问题。

#!/bin/bash
paste -d "\n\n" $1 $2  | sed '/^[[:space:]]*$/d'

输出是这样的:

01_01_01
02_01_01
02_01_02
01_02_01
01_02_02
02_02_01
01_02_03
02_03_01
01_03_01
02_03_02

另外我想查看每行来自哪个文件,那么如何将文件编号添加到每行的开头,如下所示:

1:01_01_01
2:02_01_01
1:01_02_01
1:01_02_02
1:01_02_03
2:02_02_01
1:01_03_01
2:02_03_01
2:02_03_02

答案1

在纯 bash 中,这可以借助文件描述符来完成。

file1="$1"; file2="$2"
__print() {
  [[ $1 ]] && { printf '1: %s\n' "$1"; }
  [[ $2 ]] && { printf '2: %s\n' "$2"; }
}
if [[ $file1 ]] && [[ $file2 ]]; then
    while true; do
      read -r f1 <&3 || break
      read -r f2 <&4 || break
      __print "$f1" "$f2"
    done 3<"${file1}" 4<"${file2}"
else
    echo "Usage: '$0 <file1> <file2>'"
fi

将为您提供如下输出:

1: 01_01_01
2: 02_01_01
2: 02_01_02
1: 01_02_01
1: 01_02_02
2: 02_02_01
1: 01_02_03
2: 02_03_01
1: 01_03_01
2: 02_03_02

答案2

您可以使用跨 shell 和实现的 POSIX grep 来完成此操作:

grep -v '^\s*$' file1 file2 file...

对于基于您输入的两个文件,输出为:

file1:01_01_01
file1:01_02_01
file1:01_02_02
file1:01_02_03
file1:01_03_01
file2:02_01_01
file2:02_01_02
file2:02_02_01
file2:02_03_01
file2:02_03_02

然后您可以使用sedsort进行进一步格式化。

在脚本中:

#!/bin/sh
grep -v '^\s*$' "$@"

相关内容