迭代文件夹中的文件并删除列中的前导/尾随空格

迭代文件夹中的文件并删除列中的前导/尾随空格

我有一个包含多个这种格式的文件的文件夹>

1    Hello1    World1    Example1
2    Hello2    World2    Example2
...

分隔符是\t

我想删除每列中的所有前导/尾随空格(如果存在)。

例子

1    Hello1\s    World1    \sExample1

( \s) < 代表空间,预期输出为,

1    Hello1    World1    Example1

我不想完全删除空格,因为一个值可能包含空格,例如Hel lo

我还希望编辑当前文件而不是创建新文件。

答案1

使用 GNU sed 我们可以剪切 tabb 周围的任何空格,如图所示

$ sed -Ei -e 's/[ ]*\t[ ]*/\t/g' file

使用 awk,我们迭代字段,然后修剪字段:

$ awk -F '\t' -v OFS='\t' '
{
  for (i=1; i<=NF; ++i) {
    gsub(/^[ ]+|[ ]+$/, "", $i)
  }
}1
' file > foo && mv foo file 

答案2

您只需将 FS 设置为允许每个选项卡周围有空格,然后分配给一个字段,以在从整个记录中删除前导/尾随空格后将所有 FS 替换为 OFS:

awk -F' *\t *' -v OFS='\t' '{gsub(/^ +| +$/,""); $1=$1} 1' file

使用修改后的输入来显示正在处理的前导/尾随空白并使cat -Evt制表符等可见:

$ cat -Evt file
 1^IHello1 ^IWorld1^I Example1 $
2^IHello2^IWorld2^IExample2$

$ awk -F' *\t *' -v OFS='\t' '{gsub(/^ +| +$/,""); $1=$1} 1' file | cat -Evt
1^IHello1^IWorld1^IExample1$
2^IHello2^IWorld2^IExample2$

您还说过I wish to edit the current file and not create a new one- 除非您使用ed或在编码中发挥创意(例如,awk您可以将所有输入读取到数组中,修改它,关闭您正在读取的文件,然后将修改后的数组内容写回到那个原始文件)。声称使用类型参数进行“就地编辑”的工具-i实际上会创建一个新文件来写入结果,然后用新文件覆盖原始文件,就像手动写入cmd file > tmp && mv tmp文件一样。

说了这么多,如果你想要像我刚才描述的那样进行伪就地编辑,就像使用 GNU sed 一样sed -i ...,使用 GNU awk 也可以这样做:

awk -i inplace -F' *\t *' -v OFS='\t' '{gsub(/^ +| +$/,""); $1=$1} 1' file

如果你确实想要在没有临时文件的情况下进行编辑,那么如果您的文件足够小以适合内存,您可以使用任何 awk 执行以下操作:

$ cat -Evt file
 1^IHello1 ^IWorld1^I Example1 $
2^IHello2^IWorld2^IExample2$

$ cat tst.awk
BEGIN {
    FS = " *\t *"
    OFS = "\t"
}
{
    gsub(/^ +| +$/,"")
    $1 = $1
    recs[NR] = $0
}
END {
    close(FILENAME)
    for (i=1; i<=NR; i++) {
        print recs[i] > FILENAME
    }
}

$ awk -f tst.awk file

$ cat -Evt file
1^IHello1^IWorld1^IExample1$
2^IHello2^IWorld2^IExample2$

close(FILENAME)可能不是必需的,因为我预计输入文件在进入 END 部分时已经关闭,但这不会造成伤害。

相关内容