如何preserve在AWK字段之间的空白原创? [英] How to preserve the original whitespace between fields in 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屋!