迴聲重定向附加一個空格
有人可以幫助我嗎?我正在嘗試創建很多文件,但是當我嘗試使用 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 中的
awk
可以“重定向”,其方式與您在 shell 中重定向輸出的方式幾乎相同,使用>
後跟文件名。您似乎想要使用的文件名是第二個欄位中的任何內容,並
.tmp
附加。這意味著您可以使用以下單個
awk
命令替換問題中的整個循環:awk -F ',[[:blank:]]*' '{ print $1 > ($2 ".tmp") }' limpio.tmp
該表達式計算為添加到第二個欄位中的任何內容所
($2 ".tmp")
產生的字元串。.tmp
使用
>
with>>
代替>
,則第一個這裡沒有內置的健全性檢查,因此上述內容可能會破壞系統上任何您具有寫入權限的重要文件,具體取決於輸入第二列中的內容。
如果您使用 GNU
awk
,那麼這就是您需要做的所有事情。但是,如果您使用其他一些awk
並且需要寫入大量文件,您可能需要close()
在處理文件時手動呼叫它們,或者您可能會用完可用的文件描述符。awk -F ',[[:blank:]]*' '{ fn = $2 ".tmp"; print $1 >>fn; close(fn) }' limpio.tmp
在這裡,我將輸出文件名保存在一個變數中,
fn
. 然後我將輸出附加到該文件,然後關閉該文件。這確保我不會耗盡可用的文件描述符,但如果我需要再次執行該命令,它還需要我始終>>
使用awk
GNU
awk
會跟踪打開了多少文件描述符,並在需要時開始關閉它們(如果以後需要將更多數據寫入文件,則重新打開文件以進行附加)。也可以看看: