我有这个 AWK 脚本。
awk -v line="    foo    bar  " 'END
 {
   gsub(/^ +| +$/,"", line);
   gsub(/ {2,}/, " ", line);
   print line
 }' \
somefile.txt
输入文件(somefile.txt)与我的问题无关。模式后面的部分END用于修剪变量中的多余空格line并将其打印出来。像这样:
foo bar
我试图看看是否有更好、更紧凑的方法可以在 AWK 中做到这一点。使用gsub删除几个多余的空格非常麻烦。它很难阅读,维护者也很难理解它的作用(特别是如果以前从未使用过 AWK)。关于如何使其更短或更明确的任何想法?
谢谢!
**编辑**
AWK 变量line在 awk 处理输入文件期间被过滤,我想修剪之后留下的多余空格。
正如您开始做的那样,另一个选项gsub()可以这样做:
awk '{gsub(/  +/," "); sub(/^ /,""); sub(/ $/,"")}1' <<< "    foo    bar  "
第一次调用将gsub()所有多个空格合并到字段之前/之间的单个空格。第二个sub(/^ /,"")仅修剪字符串前面保留的单个空格,最后一个sub(/ $/,"")修剪尾随空格。
任何一种方法都效果很好。根据您的实际数据和FS价值,可能会偏爱其中一个,但如果不了解更多,它们几乎是一种洗礼。
使用/输出示例
$ awk '{gsub(/  +/," "); sub(/^ /,""); sub(/ $/,"")}1' <<< "    foo    bar  "
foo bar
对于当前示例,另一个选项可能是通过首先将 line 的值设置为输入记录,然后使用来重新计算输入记录的文本$1=$1
awk -v line="    foo    bar  " \'END {$0=line; $1=$1; print}\' somefile.txt\n输出(引号只是为了清楚起见,没有前导或尾随空格)
\n"foo bar"\nEd Morton 的评论中描述了如何删除空格的内部工作原理:
\n设置 \xc2\xa0 \xc2\xa0 或对 \xc2\xa0 \xc2\xa0$0=line进行任何其他更改都会触发重新计算字段。$0
使用$1=$1\xc2\xa0 会触发 \xc2\xa0记录\xc2\xa0 被重新计算,因为它将从现有字段中重建,从而剥离前导/尾随空白并用单个连续空白替换所有其他链空白字符(假设使用默认的 FS 和 OFS)。