修剪 AWK 中的多余空格

Mis*_*rev 3 bash awk

我有这个 AWK 脚本。

awk -v line="    foo    bar  " 'END
 {
   gsub(/^ +| +$/,"", line);
   gsub(/ {2,}/, " ", line);
   print line
 }' \
somefile.txt
Run Code Online (Sandbox Code Playgroud)

输入文件(somefile.txt)与我的问题无关。模式后面的部分END用于修剪变量中的多余空格line并将其打印出来。像这样:

foo bar
Run Code Online (Sandbox Code Playgroud)

我试图看看是否有更好、更紧凑的方法可以在 AWK 中做到这一点。使用gsub删除几个多余的空格非常麻烦。它很难阅读,维护者也很难理解它的作用(特别是如果以前从未使用过 AWK)。关于如何使其更短或更明确的任何想法?

谢谢!

**编辑**

AWK 变量line在 awk 处理输入文件期间被过滤,我想修剪之后留下的多余空格。

Dav*_*ica 6

正如您开始做的那样,另一个选项gsub()可以这样做:

awk '{gsub(/  +/," "); sub(/^ /,""); sub(/ $/,"")}1' <<< "    foo    bar  "
Run Code Online (Sandbox Code Playgroud)

第一次调用将gsub()所有多个空格合并到字段之前/之间的单个空格。第二个sub(/^ /,"")仅修剪字符串前面保留的单个空格,最后一个sub(/ $/,"")修剪尾随空格。

任何一种方法都效果很好。根据您的实际数据和FS价值,可能会偏爱其中一个,但如果不了解更多,它们几乎是一种洗礼。

使用/输出示例

$ awk '{gsub(/  +/," "); sub(/^ /,""); sub(/ $/,"")}1' <<< "    foo    bar  "
foo bar
Run Code Online (Sandbox Code Playgroud)


The*_*ird 5

对于当前示例,另一个选项可能是通过首先将 line 的值设置为输入记录,然后使用来重新计算输入记录的文本$1=$1

\n
awk -v line="    foo    bar  " \'END {$0=line; $1=$1; print}\' somefile.txt\n
Run Code Online (Sandbox Code Playgroud)\n

输出(引号只是为了清楚起见,没有前导或尾随空格)

\n
"foo bar"\n
Run Code Online (Sandbox Code Playgroud)\n

Ed Morton 的评论中描述了如何删除空格的内部工作原理:

\n

设置 \xc2\xa0 \xc2\xa0 或对 \xc2\xa0 \xc2\xa0$0=line进行任何其他更改都会触发重新计算字段$0

\n

使用$1=$1\xc2\xa0 会触发 \xc2\xa0记录\xc2\xa0 被重新计算,因为它将从现有字段中重建,从而剥离前导/尾随空白并用单个连续空白替换所有其他链空白字符(假设使用默认的 FS 和 OFS)。

\n