簡體   English   中英

如何在sed中將命令的結果作為字符串參數輸入

[英]How to input a command's result as a string argument in sed

我想在我的bash終端上執行以下命令:

sed -i '6i `sed '1!d' input.in`' out

通過它我可以在sed '%1!d' input.in命令的結果的文件輸出的第6行插入(替換-i選項)。 我沒有發現任何有用的東西,並且嘗試了`com`,$(com)和com | sed sed '%1!d' input.in ,其中com代表sed '%1!d' input.in 我更改整個命令的語法沒有任何問題,但是我希望將其寫在終端使用sed的一行中。

感謝您的收聽,等待您的答復。

對於EdMorton:

Example Input:

input.in:
into a lake.

out:
Mary was runing around a pond and fell
into a lake.


Mary fell into a what?

Desired Output:
Mary was runing around a pond and fell
into a lake.


Mary fell into a what?
into a lake.

嘗試在標准輸入而不是i上使用r

sed '%1!d' input.in |
sed -i '6r /dev/stdin' out

如果您的平台不支持/dev/stdin/dev/fd/0 ,請查看您的sed支持-表示標准輸入...,或者在最壞的情況下,使用臨時文件。

正如評論者已經指出的那樣,在大多數sed方言中, %1!d似乎不是有效的命令,但是在此基本上不重要。 (如果只打印第一行,則可能是sed '1!d' ,盡管sed 'p;q'更有效。)

sed用於單行替換,僅此而已。 對於其他任何事情,您都應該使用awk。

給定此修改后的輸入文件

$ cat input.in
a Windows folder C:\Windows\Temp

這是您在評論中發布的sed解決方案的作用:

$ sed '1!d' input.in > temp.of.in && sed "6i `cat temp.of.in`" out
Mary was runing around a pond and fell
into a lake.


Mary fell into a what?
a Windows folder C:WindowsTemp

這是awk解決方案在沒有臨時文件的情況下可以更有效,更准確地執行的操作:

$ awk 'NR==1{x=$0;nextfile} FNR==6{print x} 1' input.in out
Mary was runing around a pond and fell
into a lake.


Mary fell into a what?
a Windows folder C:\Windows\Temp

請注意,awd解決方案保留了路徑分隔符反斜杠,而sed則將其刪除。 還要注意,您確實應該在sed命令行的末尾添加&& rm temp.of.in以清理臨時文件,並且應該使用$(..)執行命令,而不要使用過時的反引號。

awk解決方案對;nextfile使用GNU awk,對於其他awks,您可以將其替換為}NR==FNR{next或類似名稱,但由於您使用的是GNU sed,所以我也假設您也有GNU awk。

請注意,如果您對DID渴望使用sed並接受它並不能完全重現輸入,那么可以使用更簡單,更有效的方法來執行當前腳本的操作,例如:

sed "6i $(head -1 input.in)" out

甚至是您最初的想法,只需重寫一下即可消除過時的反引號和1!d否定邏輯:

sed "6i $(sed -n '1p' input.in)" out

但是請認真使用-只需使用awk。 除了在單個行上進行簡單替換以外,其他任何事情都比sed健壯,高效,清晰,可移植,可擴展等。

編輯以解決您的評論中的問題:

  1. 您能解釋一下awk上的參數嗎? 沒有參數,只有一個腳本說:如果這是從第一個文件讀取的第一行,請將其保存在變量x中,然后移至下一個文件。 如果這是第二個文件的第6行,則打印變量x的內容。 對於第二個文件的每一行,打印它( 1是慣用但乍一看有點棘手-這是一個真正的條件,因此調用打印當前輸入的默認操作,相當於只是寫{print}
  2. 我如何將輸出文件替換為out文件(不使用'>'),如選項-i在sed上所做的,並避免將其打印到stdout? 就像GNU sed has -i ,GNU awk has -i inplace 但是要小心,因為與sed一樣,它適用於每個輸入文件,因此,如果您不打印第一個文件的內容,那么當腳本完成后,第一個文件將為空。 有多種處理方法,包括簡單地打印文件1中的行或在BEGINFILE / ENDFILE塊中打開/關閉就地編輯,請參閱https://www.gnu.org/software/gawk/manual/gawk.html# Extension-Sample-Inplace ,但是恕我直言, awk'script'file1 awk 'script' file1 file2 > temp && mv temp file2是最簡單和最清晰的,並且可移植到所有awk / seds /任何地方。
  3. 另外,是否有一個多行解決方案,例如從“ input.in”中取出“第1至4行”,並將其放在“ out”的第6行中? 沒問題:

awk '
    NR==FNR { if (NR<=4) x=x $0 ORS; else nextfile }
    FNR==6 { printf "%s", x }
    { print }
' input.in out

為了清楚起見,我將前一個腳本的1更改為{ print }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM