xargs將stdin轉換為命令列引數

2021-07-04 12:09:44 字數 3234 閱讀 8419

我們可以用管道將乙個命令的stdout(標準輸出)重定向到另乙個命令的stdin(標準輸入)。例如:

$cat  foo.txt |  grep  「test」

但是,有些命令只能以命令列引數的形式接受收據,而無法通過stdin接受資料流。在這種情況下,我們沒法用管道來提供那些只有通過命令列引數才能提供的資料。

只有另闢蹊徑。xargs是乙個很有用的命令,它擅長將標準輸入資料轉換成命令列引數。

單行命令是乙個命令序列,各命令之間不使用分號,而是使用管道操作符進行連線。精心編寫的單行命令可以更高效、更簡捷地完成任務。就文字處理而言,需要具備紮實的理論和實踐才能夠寫出適合的單行命令解決方法。xargs就是構建單行命令的重要元件之一。

xargs命令用該緊跟在管道操作符之後。它以標準輸入作為主要的源資料流。

command  | xargs

----->>

xargs命令能將stdin接收到的資料重新格式化,再將其作為引數提供給其他命令。

xargs如何格式化資料:

-d選項,指明定界符

-n選項,指明每行最大的引數數量n

範例:將多行輸入轉換成單行輸出

只需將換行符移除,在用」 」(空格)進行替換,就可以實現。xargs預設將空格作為定界符。xargs沒有指定引數時,預設能將換行符替換成空格。

$cat  example.txt

1  2 3  4  5  6

7  8 9  10

11  12

$catexample.txt  |  xargs

1  2 3  4  5 6  7  8 9  10  11  12

範例:將單行輸入轉換成多行輸出

$cat  examole.txt  | xargs  -n  3

1  2  3

4  5  6

7  8  9

10  11  12

$echo  「splitxsplitxsplitxsplit」  | xargs  -d  x

split splitsplit split

$echo  「splitxsplitxsplitxsplit」  | xargs  -d  x –n 2

split split

split split

xargs

的初衷是將引數列表轉換成小塊分段傳給其他命令,以避免引數列表過長。

編制乙個定製版的echo來更好的理解xargs。

#!/bin/bash

#myecho.sh

echo  $*』#』

當引數被傳遞給myecho.sh後,它會將這些引數列印出來,並以#字元作為結尾。例如:

$./myecho.sh  arg1 arg2

arg1  arg2#

看下面問題:

有乙個包含引數列表的檔案(每行乙個引數)。

每次提供乙個引數:

./myecho.sh  arg1

./myecho.sh  arg2

./myecho.sh arg3

每次提供多個引數:

./myecho.sh  arg1  arg2

./myecho.sh  arg3

一次性提供:

./myecho.sh  arg1 arg2  arg3

上面的問題,也可以用xargs實現。我們將引數儲存到args.txt。

$cat  args.txt

arg1

arg2

arg3

$cat  args.txt |  xargs  -n 1  ./myecho.sh

arg1#

arg2#

arg3#

通過#號,可以知道myecho.sh執行了3次。

$cat  args.txt |  xargs  -n 2  ./myecho.sh

arg1  arg2#

arg3#

#catargs.txt  |  xargs ./myecho.sh

arg1  arg2 arg3#

xargs不加引數時,預設將換行符替換成空格。就好像是預設,為這種,從引數列表檔案中獲取引數提供方便服務的。(想想,如果沒有這種預設服務,那麼想要將擁有多行文字的args.txt中的引數一次性提取,你會怎麼做?)

上面例子中,我們直接為myecho.sh提供引數。這些引數都源於args.txt檔案。但實際上除了它們外,我們還需要一些固定不變的命令引數。思考下面這種命令格式:

./myecho.sh  -p arg1 –l

在上面的命令執行過程中,arg1是唯一的可變文字,其餘部分保持不變。我們應該從args.txt中讀取引數,並按照下面的方式提供給命令:

./myecho.sh  -p  arg1 -l

./myecho.sh  -p  arg2 -l

./myecho.sh  -p  arg3 -l

xargs有乙個選項-i,可以提供上面這種形式的命令執行序列。我們可以用-i執行乙個替換字串,這個字串在xargs擴充套件時會被替換掉。當-i與xargs結合使用,對於每乙個引數命令都會執行一次。

$cat  args.txt  | xargs  -i  {} ./myecho.sh  -p  {}  -l

-p  arg1  -l#

-p  arg2  -l#

-p  arg3  -l#

結合find使用xargs:

兩者結合使用可以讓任務變得更輕鬆。不過,人們通常卻是以一種錯誤的組合方式使用它們。例如:

$find  .  –type f  -name  「*.txt」 -print  | xargs  rm  -f

這樣做很危險。有時可能會刪除不必要刪除的檔案。我們沒法**分隔find命令輸出結果的定界符究竟是』\n』還是』  『(空格)。很多檔名中都可能會包含空格符,而xargs很可能會誤認為它們是定界符(例如,hell text.txt會被xargs誤認為hell和text.txt)。

只要我們把find的輸出作為xargs的輸入,就必須將-print0與find結合使用,以字元null來分隔輸出。

用find匹配並列出所有.txt檔案,然後用xargs將這些檔案刪除:

$find  .  –type f  -name  「*.txt」 -print0  |  xargs -0  rm  -f

刪除所有txt檔案。xargs  -0將\0作為輸入定界符。

統計所有c程式檔案的行數:

$find  code_path  -type -f  -name  「*.c」 -print0  |  xargs -0  wc  -l

mysql將毫秒轉換為小時 將毫秒轉換為天小時分鐘

今天在專案中遇到進行計算流程單從開始到結束所花費的時間,樣式是xx天xx小時xx秒,有天顯示天,沒有就不顯示 獻上 package com.project.model.work public class dateformat 將毫秒轉化為天時分秒毫秒 public static string for...

將QString轉換為char

官方說明 注意在呼叫qbytearray.data 之前,必須要先顯示儲存這個bytearray。像這樣const char c str2 str2.tolatin1 data 會使程式崩潰,因為qbytearray沒有被儲存,呼叫data 前是不存在的,必須先顯式呼叫一次tolatin1 再呼叫d...

將IplImage轉換為Mat

讓自己學會記錄而已。mat mat const iplimage img,bool copydata false 預設情況下,新的mat型別與原來的iplimage型別共享影象資料,轉換只是建立乙個mat矩陣頭。當將引數copydata設為true後,就會複製整個影象資料。例 iplimage ip...