如果GNU awk
是可用的,@ jaypal的簡潔和優雅的解決方案是要走的路。
這裏有一個兼容POSIX 解決方案,試圖點綴我的和交叉的T的(是什麼讓@ jaypal的解決方案不符合的是使用含有一種以上(文字)字符的RS
(記錄分隔符)值):
- 它消除
zone:
從輸出,作爲請求由OP
- 它不會在開始打印一個額外
\n
或省略了後一個。
- 它安全地使用
printf
,使用格式參數,以避免意外控制字符。擴大輸入線。
awk '{
if ($1=="zone:") { sep=(notFirst++ ? ORS : ""); $1=""; $0=substr($0,2) }
else { sep=OFS; $1=$1; }
printf "%s%s", sep, $0
}
END { print }
' file
這是同樣的程序的大量註釋版本,希望能解釋的awk
這裏使用的更神祕的特點:
awk '
{
if ($1=="zone:") { # Zone lines
# Determine the separator to *precede* the output line:
# ORS, the output *record* separator, which defaults to \n
# - unless it is the very first line.
# Net effect: zone lines start new output lines.
sep=(notFirst++ ? ORS : "");
# Remove the `zone:` field by setting the first field,
# $1, to an empty string.
# Note: This causes the entire line to be rebuilt by joining the
# fields with OFS, the output field separator, which defaults
# to a space. Multiple adjacent space chars. are folded into
# one in the process.
$1="";
# Remove the space char. at the beginning of the rebuilt
# line that stems from setting $1 to an empty string.
$0=substr($0,2)
} else { # Non-zone lines
# Determine the separator to *precede* the output line:
# just the regular output *field* separator (space),
# effectively causing this line to be appended to the
# previous one.
sep=OFS;
# Trigger rebuilding the line so as to fold
# multiple adjacent space chars. into one.
$1=$1;
}
# Output the separator followed by the rebuilt line.
printf "%s%s", sep, $0
}
# Since the `printf` statement above never outputs
# a *terminating* \n, we output one at the very end.
END { print }
' file
刪除空格:awk'{$ 1 = $ 1; printf(/^zone /)?RS $ 0:FS $ 0}'file' – Jotne
對於關鍵字'/^zone /',這個命令是精細。但是,如果按照「前幾個字符爲空」的規則進行處理,則不能 – BMW