如何preserve在AWK字段之间的空白原创? [英] How to preserve the original whitespace between fields in awk?

查看:127
本文介绍了如何preserve在AWK字段之间的空白原创?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在处理与 AWK 输入,有时我想编辑的领域之一,不接触任何东西。试想一下:

  $ ls -l命令| AWK 1
总88
-rw-R - R-- 1千斤顶19年6月8日2013年qunit,1.11.0.css
-rw-R - R-- 1千斤顶56908 2013年6月19日qunit,1.11.0.js
-rw-R - R-- 1千斤顶4306 12月29日9时16 test1.html
-rw-R - R-- 1千斤顶5476 12月7日08:09 test1.js

如果我不修改任何字段( $ 1 $ 2 ,...),应有尽有是pserved因为它是$ p $。但是,如果让我们说,我想保持只有第一场的前3个字符:

  $ ls -l命令| AWK'{$ 1 = SUBSTR($ 1,1,3)} 1'
TOT 88
-RW 1千斤顶19年6月8日2013年qunit,1.11.0.css
-RW 1千斤顶56908 2013年6月19日qunit,1.11.0.js
-RW 1千斤顶4306年12月29 09:16 test1.html
-RW 1千斤顶5476 12月7日08:09 test1.js

各个领域之间的空白原来被替换为一个简单的空间。

有没有办法来preserve领域的空白原?

更新

在这个例子中,它是比较容易编辑的前4场。但如果我只想保留的第一个字母 $ 5 为了得到这样的输出:

  -rw-R  -  R-- 1千斤顶8Ĵ19 2013 qunit,1.11.0.css
-rw-R - R-- 1千斤顶56908Ĵ19 2013 qunit,1.11.0.js
-rw-R - R-- 1千斤顶4306ð29 09:16 test1.html
-rw-R - R-- 1千斤顶5476 D 7 08:09 test1.js


解决方案

我知道这是一个老问题,但我认为必须有更好的东西。这个答案是对那些无意中发现了这个问题,而搜索。虽然在网络上环顾四周,我不得不说 @哈康Hægland有最好的答案,这就是我在第一次使用。

但这里是我的解决方案。使用<一个href=\"https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html#Splitting-By-Content\"相对=nofollow> FPAT 。它可以设置一个普通的前pression说一个领域应该是什么。

  FPAT =([[:空间:]] * [[:alnum:] [:PUNCT:] [:数字:]] +);  

在这种情况下,我想说的领域应与零个或多个空格字符开始和除空白字符,基本上任何其他字符结束。 这里是一个链接,如果你无法理解 POSIX 支架前pressions。

此外,输出字段更改为 OFS =; 分离器,因为一旦该行已被操纵,输出将增加一个额外的空格,如果你的分隔符不要将其从默认更改OFS。

我用同样的例子来测试。

  $猫的例子,output.txt的
-rw-R - R-- 1千斤顶19年6月8日2013年qunit,1.11.0.css
-rw-R - R-- 1千斤顶56908 2013年6月19日qunit,1.11.0.js
-rw-R - R-- 1千斤顶4306 12月29日9时16 test1.html
-rw-R - R-- 1千斤顶5476 12月7日08:09 test1.js

  $的awk'BEGIN {FPAT =([[:空间:]] * [[:alnum:] [:PUNCT:] [:数字:] +); OFS =; } {$ 6 = SUBSTR($ 6,1,2);打印$ 0; }例如,output.txt的
-rw-R - R-- 1千斤顶8Ĵ19 2013 qunit,1.11.0.css
-rw-R - R-- 1千斤顶56908Ĵ19 2013 qunit,1.11.0.js
-rw-R - R-- 1千斤顶4306ð29 09:16 test1.html
-rw-R - R-- 1千斤顶5476 D 7 08:09 test1.js

记住。该领域现在有前导空格。因此,如果字段需要别的东西来代替,你可以做

  LEN =长度($ 1);
$ 1 = sprintf的(%(LEN)S,-42 - );

  $的awk'BEGIN {FPAT =([[:空间:]] * [[:alnum:] [:PUNCT:] [:数字:] +); OFS =; } {如果(NR == 1)为{len =长度($ 1); $ 1 = sprintf的(%(LEN)的s,-39-); }打印$ 0; }例如,output.txt的
      -38- 1千斤顶19年6月8日2013年qunit,1.11.0.css
-rw-R - R-- 1千斤顶56908 2013年6月19日qunit,1.11.0.js
-rw-R - R-- 1千斤顶4306 12月29日9时16 test1.html
-rw-R - R-- 1千斤顶5476 12月7日08:09 test1.js

When processing input with awk, sometimes I want to edit one of the fields, without touching anything else. Consider this:

$ ls -l | awk 1
total 88
-rw-r--r-- 1 jack jack     8 Jun 19  2013 qunit-1.11.0.css
-rw-r--r-- 1 jack jack 56908 Jun 19  2013 qunit-1.11.0.js
-rw-r--r-- 1 jack jack  4306 Dec 29 09:16 test1.html
-rw-r--r-- 1 jack jack  5476 Dec  7 08:09 test1.js

If I don't edit any of the fields ($1, $2, ...), everything is preserved as it was. But if let's say I want to keep only the first 3 characters of the first field:

$ ls -l | awk '{$1 = substr($1, 1, 3) } 1'
tot 88
-rw 1 jack jack 8 Jun 19 2013 qunit-1.11.0.css
-rw 1 jack jack 56908 Jun 19 2013 qunit-1.11.0.js
-rw 1 jack jack 4306 Dec 29 09:16 test1.html
-rw 1 jack jack 5476 Dec 7 08:09 test1.js

The original whitespace between all fields is replaced with a simple space.

Is there a way to preserve the original whitespace between the fields?

UPDATE

In this sample, it's relatively easy to edit the first 4 fields. But what if I want to keep only the 1st letter of $5 in order to get this output:

-rw-r--r-- 1 jack jack     8 J 19  2013 qunit-1.11.0.css
-rw-r--r-- 1 jack jack 56908 J 19  2013 qunit-1.11.0.js
-rw-r--r-- 1 jack jack  4306 D 29 09:16 test1.html
-rw-r--r-- 1 jack jack  5476 D  7 08:09 test1.js

解决方案

I know this is an old question but I thought there had to be something better. This answer is for those that stumbled onto this question while searching. While looking around on the web, I have to say @Håkon Hægland has the best answer and that is what I used at first.

But here is my solution. Use FPAT. It can set a regular expression to say what a field should be.

 FPAT = "([[:space:]]*[[:alnum:][:punct:][:digit:]]+)";

In this case, I am saying the field should start with zero or more blank characters and ends with basically any other character except blank characters. Here is a link if you are having trouble understanding POSIX bracket expressions.

Also, change the output field to OFS = ""; separator because once the line has been manipulated, the output will add an extra blank space as a separator if you don't change OFS from its default.

I used the same example to test.

$ cat example-output.txt
-rw-r--r-- 1 jack jack     8 Jun 19  2013 qunit-1.11.0.css
-rw-r--r-- 1 jack jack 56908 Jun 19  2013 qunit-1.11.0.js
-rw-r--r-- 1 jack jack  4306 Dec 29 09:16 test1.html
-rw-r--r-- 1 jack jack  5476 Dec  7 08:09 test1.js

$ awk 'BEGIN { FPAT = "([[:space:]]*[[:alnum:][:punct:][:digit:]]+)"; OFS = ""; } { $6 = substr( $6, 1, 2);  print $0; }' example-output.txt
-rw-r--r-- 1 jack jack     8 J 19  2013 qunit-1.11.0.css
-rw-r--r-- 1 jack jack 56908 J 19  2013 qunit-1.11.0.js
-rw-r--r-- 1 jack jack  4306 D 29 09:16 test1.html
-rw-r--r-- 1 jack jack  5476 D  7 08:09 test1.js

Keep in mind. The fields now have leading spaces. So if the field needs to be replaced by something else, you can do

len = length($1); 
$1 = sprintf("%"(len)"s", "-42-");

$ awk 'BEGIN { FPAT = "([[:space:]]*[[:alnum:][:punct:][:digit:]]+)"; OFS = ""; } { if(NR==1){ len = length($1); $1 = sprintf("%"(len)"s", "-42-"); } print $0; }' example-output.txt
      -42- 1 jack jack     8 Jun 19  2013 qunit-1.11.0.css
-rw-r--r-- 1 jack jack 56908 Jun 19  2013 qunit-1.11.0.js
-rw-r--r-- 1 jack jack  4306 Dec 29 09:16 test1.html
-rw-r--r-- 1 jack jack  5476 Dec  7 08:09 test1.js

这篇关于如何preserve在AWK字段之间的空白原创?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆