Làm thế nào để xen kẽ các dòng của hai hoặc nhiều tập tin?


10

Tôi đã cố gắng để có được 2 tập tin đầu ra trong một tập tin duy nhất. Tôi đã thử lệnh dưới đây:

cat file1 file2

nhưng ở đây file2dữ liệu đang nối vào file1.

Cái tôi cần là file1dòng thứ nhất theo sau là file2dòng file1thứ nhất và dòng thứ hai theo sau là file2dòng thứ hai, v.v.

Ai đó có thể cho tôi biết làm thế nào để làm điều này một cách đơn giản?

Câu trả lời:


17

Có một ứng dụng cho điều đó!

$ cat file1
file1 line1
file1 line2

$ cat file2
file2 line1
file2 line2

Bây giờ, nếu bạn chuyển các tệp này làm đối số cho paste:

$ paste -d' ' file1 file2
file1 line1 file2 line1
file1 line2 file2 line2

Nếu bởi "file1 dòng thứ nhất theo sau là dòng thứ nhất của tệp2 và dòng thứ hai của tệp1 theo sau là dòng thứ hai của tệp2, v.v.", bạn có nghĩa là bạn muốn một dòng mới giữa mỗi dòng được dán, chỉ cần điều chỉnh -dtùy chọn (dấu phân cách).

$ paste -d'\n' file1 file2
file1 line1
file2 line1
file1 line2
file2 line2

2

AwIX POSIX; điều này hoạt động với số lượng tệp tùy ý và các tệp thậm chí không phải có cùng số lượng dòng. Kịch bản tiếp tục cho đến khi tất cả các tệp nằm ngoài dòng:

BEGIN {
  do {
    br = ch = 0
    while (++ch < ARGC)
      if (getline < ARGV[ch]) {
        printf ch < ARGC - 1 ? $0 FS : $0 RS
        br = 1
      }
  } while (br)
}

Có một vấn đề với nó, nếu đầu vào chứa các ký tự '%' thì nó đã cố gắng đánh giá chúng bên trong printf. Cập nhật của tôi sẽ là (Tôi không chắc điều này là hoàn toàn chính xác):printf "%s", ((ch < ARGC - 1) ? $0 FS : $0 RS)
Scala William

0

Giải pháp bash nhanh

# Takes as many file arguments as needed
function InterleaveFiles {

    local counter=0
    local hasLine=true

    while [ $hasLine == true ]; do
            hasLine=false
            for i in "$@"; do
                    line=$(awk 'NR == num_line {print; exit}' num_line=$((counter+1)) "$i")
                    if [ -n "$line" ]; then
                            echo "$line"
                    hasLine=true
                    fi
            done
            counter=$((counter+1))
    done
}

InterleaveFiles file1 file2 file3 file4


-2
paste -d '\n' file1 file2 > file3

trong đó file1file2là các tệp đầu vào và file3sẽ là đầu ra được tạo.


1
Chào mừng bạn đến với Sàn giao dịch U & L! Câu trả lời này gần giống với câu trả lời của terdon . Trong trường hợp bạn nghĩ rằng bạn có thể cải thiện câu trả lời, nhưng không cung cấp thông tin mới đáng kể, vui lòng xem xét đề xuất chỉnh sửa cho câu trả lời hiện có . Câu trả lời cũng được sắp xếp lại dựa trên biểu quyết, vì vậy mỗi câu trả lời nên tự đứng hoặc tham khảo câu trả lời khác. Đó là lý do tại sao các onelin shell phải được kèm theo một mô tả giải thích hoạt động của chúng.
Thomas Nyman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.