Shell

在程序之間傳遞多個文件的內容,同時保持內容分開

  • July 26, 2015

我想讀入一些文件並將它們的輸出通過管道傳輸到後續程序,同時仍將它們作為單獨的數據管道進行維護。

program1 *.txt | program2 | program3 folder

我知道上述語法可以為單個數據流完成什麼,但我正在考慮在整個操作過程中保持文件分開。以上將轉化為以下內容:

  1. program1 讀取文本文件和管道到 program2
  2. program2 單獨處理數據並通過管道傳輸到 program3
  3. program3 將數據寫入與原始文件名相同的文件夾中的文件

這種操作目前是 Gulp 等建構工具的領域,但我正在嘗試看看 shell 是否可以完全替換它們。由於程序被編寫為只處理一個stdin,這似乎不可行。

多個文件的讀取和寫入不是問題,因為我將在程序本身中處理它。

我研究了以下內容,但它們似乎不是正確的解決方案:

  • tee命令_
  • 文件描述符
  • 換人

一種可能的方法是為每個單獨的文件創建一個程序,並在某處維護一個文件名列表,但我希望有更優雅的東西。

管道,就像任何文件一樣,是一個文本流(更準確地說,是一個字節流)。Unix 的基本建構塊往往很簡單。流程之間的互動主要基於非結構化數據。作業系統不提供具有由文件名標記的多個流的通信通道。如果程序需要這個,他們需要自己安排——並且單獨的管道,每個流一個,將是最自然的實現。

如果program2並且program3對每個流獨立操作,請為每個文件執行一個副本。要按順序執行它們,請使用 shell 循環。與管道一樣,循環是將程序聯繫在一起的外殼功能之一。為了告訴program3將輸出放在哪裡,通常的介面是program3寫入其標準輸出,並在 shell 中使用重定向構造將輸出定向到文件。shell 提供了一些基本的字元串操作結構來建構文件名;這裡只是串聯。

for x in *.txt; do
 program1 "$x" | program2 | program3 >"folder/$x"
done

如果程序在 IO 上很輕但 CPU 密集,並且您有多個 CPU,您可能希望並行執行它們。使用最新的 GNU 工具,您可以用來xargs並行執行程序。將系統上的 CPU 數量作為參數傳遞給-P. 由於xargs需要執行的命令是管道,因此您需要使其呼叫 shell。

find -maxdepth 1 -name '*.txt' -print0 |
xargs -0 -n 1 -P 4 sh -c 'program1 "$1" | program2 | program3 >"$0/$1"' "folder"

您可以使用GNU parallel而不是 xargs 讓它自動確定係統上的 CPU 數量。

parallel sh -c 'program1 "$1" | program2 | program3 >"$0/$1"' "folder" ::: *.txt

如果您需要單個實例program2program3處理多個文件,則需要使用自定義介面設計這些程序以接收多個管道作為輸入。沒有標準的方法可以做到這一點。一種方法是讓他們呼叫提供輸入的程序。這將類似於方式xargs,並被parallel告知呼叫什麼程序來處理它們的輸出。

引用自:https://unix.stackexchange.com/questions/218382