我有一个包含多个这种格式的文件的文件夹>
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 部分时已经关闭,但这不会造成伤害。