Bash

迴聲重定向附加一個空格

  • November 28, 2021

有人可以幫助我嗎?我正在嘗試創建很多文件,但是當我嘗試使用 echo 寫入它時,它會添加一個空格和單引號,例如:

' (here is the space)  file.tmp' 

'  file1.tmp'

'  file3.tmp' 

程式碼是這樣的。


cat limpio.tmp | while read line; do
 srcip=$(echo $line | awk -F"," '{print $1}')
 destip=$(echo $line | awk -F"," '{print $2}')
 port=$(echo $line | awk -F"," '{print $NF}')
 echo "${srcip}" >> "$destip.tmp"
done

當我嘗試用 cat 迭代和查看其內容時,問題就來了,但由於空格而我不能。

非常感謝您

echo實用程序插入空格,但僅在輸出參數時作為參數之間的分隔符:

$ echo 1    2 3       4 'A B     C'
1 2 3 4 A B     C

B和之間的空格C被保留,因為它們是相同參數的一部分echo

所以不是echo插入空格,而是您的數據已經包含空格。

我假設您看到的單引號是ls系統輸出的一部分(請參閱為什麼 ’ls’ 突然用單引號中的空格包裝項目?),或者可能是執行時 shell 的跟踪輸出的一部分set -x活動的(請參閱為什麼 bash 在執行命令之前將單引號添加到命令中未加引號的失敗路徑名擴展?)。也就是說,它實際上不是文件名的一部分,而只是一些工具呈現名稱的方式。

例如,假設您的輸入看起來像

174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144

您會注意到逗號分隔符後有空格。如果您使用逗號作為分隔符從上述文件中讀取第二個欄位,您將因此保留欄位開頭的空格,如果您使用該數據作為文件名,則文件名將以空格開頭。

(細心的讀者會注意到問題中的程式碼使用了未引用的變數line,這意味著 shell 會在空格上拆分變數的值並顯示echo單獨的參數,例如174.18.418.83,,10.404.401.94,53144。所以從某種意義上說,這是真的它是echo插入需要刪除的空格,但如果數據中沒有空格/製表符,則不會這樣做。另請參閱何時需要雙引號?

解決方案是使用逗號和任何後續空白字元作為分隔符awk

awk -F ',[[:blank:]]*' '{ print $2 }'

該表達式,[[:blank:]]*匹配逗號後跟任意數量的空白字元。“空白”字元是空格或製表符。, *如果您知道您有文字空格,則可以將其更改為(“comma, space, asterisk”)。

現在避免為輸入文件中的每一行呼叫awk 三次

in 中的print語句awk可以“重定向”,其方式與您在 shell 中重定向輸出的方式幾乎相同,使用>後跟文件名。

您似乎想要使用的文件名是第二個欄位中的任何內容,並.tmp附加。

這意味著您可以使用以下單個awk命令替換問題中的整個循環:

awk -F ',[[:blank:]]*' '{ print $1 > ($2 ".tmp") }' limpio.tmp

該表達式計算為添加到第二個欄位中的任何內容所($2 ".tmp")產生的字元串。.tmp

使用>withprint意味著輸出文件將在第一個創建或截斷(清空),print並且只有print在相同名稱之後才會追加新行。如果您要使用>>代替>,則第一個print將附加到文件而不是截斷文件。

這裡沒有內置的健全性檢查,因此上述內容可能會破壞系統上任何您具有寫入權限的重要文件,具體取決於輸入第二列中的內容。

如果您使用 GNU awk,那麼這就是您需要做的所有事情。但是,如果您使用其他一些awk並且需要寫入大量文件,您可能需要close()在處理文件時手動呼叫它們,或者您可能會用完可用的文件描述符。

awk -F ',[[:blank:]]*' '{ fn = $2 ".tmp"; print $1 >>fn; close(fn) }' limpio.tmp

在這裡,我將輸出文件名保存在一個變數中,fn. 然後我將輸出附加到該文件,然後關閉該文件。這確保我不會耗盡可用的文件描述符,但如果我需要再次執行該命令,它還需要我始終>>使用print並手動清理(刪除)輸出文件。awk

GNUawk會跟踪打開了多少文件描述符,並在需要時開始關閉它們(如果以後需要將更多數據寫入文件,則重新打開文件以進行附加)。

也可以看看:

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