Wildcards
連接來自不同目錄的多個文件
我想連接來自不同目錄的多個文件。
目錄 1:
Chr1
包含(在此範例中)四個文件:ABC.1 DEF.1 GHI.1 JKL.1
目錄 2:
Chr2
ABC.2 DEF.2 GHI.2 JKL.2
有 22 個目錄。每個文件有 20 列和一個標題。所有文件的標題都相同。
我想將所有文件連接到一個文件中(一個全域輸出文件,用於連接所有目錄中的所有文件)。
我試過這個,但這不起作用。
cat */Chr{1..22}/*.{1..22} > */final_file
它說“沒有這樣的文件或目錄”,因為沒有文件,例如chr22目錄下的文件為*.1~21。
你有什麼想法?先感謝您。
您的方法的問題在於,重複的萬用字元不會以“同步”方式解釋(=“expanded”),而是對於命令行上的每次出現都重新獨立地進行解釋。因此,您將需要使用嵌套的 shell 循環。
您可以嘗試以下 shell 腳本。請注意,它使用
bash
功能(您的問題不包括您使用的外殼)#!/bin/bash hdr=0 # initialize variable to keep track of whether the header is already printed # loop over directories for d in Chr* do # extract trailing number from dir name by removing 'Chr' part (bash feature!) n="${d#Chr}" # loop over all files for f in "$d/"*".$n" do if (( hdr == 0 )) # if header wasn't printed yet, output entire file then cat "$f" > final_file hdr=1 else # otherwise, output file content starting with line 2 tail -n +2 "$f" >> final_file fi done done
您可以命名腳本
concatenate.sh
,使其可執行,然後從所有Chr{1..22}
子目錄所在的目錄執行它。也將final_file
在該目錄中創建。請注意,我無法測試它很遠,但它不應該破壞任何東西……
只需使用
zsh
外殼:cat -- */Chr<1-22>/*.<1-22>(n) > final_file
In
zsh
,<x-y>
是一個匹配十進制整數範圍的 glob 運算符,並且n
glob 限定符切換numericglobsort
導致 glob 擴展按數字排序的選項。在另一個 shell 中,您可以執行以下操作:
zsh -c 'cat -- */Chr<1-22>/*.<1-22>(n) > final_file'
要跳過除第一個文件之外的所有文件的標題,並假設 GNU 或 busybox 實現
tail
(在使用 Linux 作為核心的系統上最常見),您可以執行以下操作:(){ cat < $1; shift; (($#)) && tail -qn +2 -- "$@" } */Chr<1-22>/*.<1-22>(n) > final_file