Results.txt
目前,我有一个包含 27k 行的文件 ( )。文件内容如下。
45008657 | A. | | Long | 0
49210987 | A. | | Steven | 3262
49600694 | A. | | Steven | 4772
467814 | A. | Rafeal | Nadal| 4133
53111047 | A. | Mike | Tyson | 13484
我需要删除多余的空白,如下所示。
cat Results.txt | tr -d " \t\r" > Results1.txt
文件(Results1.txt
)格式整齐,没有多余的空格。
45008657|A.||Long|0
49210987|A.||Steven|3262
49600694|A.||Steven|4772
467814|A.|Rafeal|Nadal|4133
53111047|A.|Mike|Tyson|13484
现在,我需要将所有字母转换为小写并附加第 2 至 4 列。
awk 'BEGIN { FS = "|" } ; { print $1"|"tolower($2) tolower($3) tolower($4)"|"$5 }' Results1.txt > Results2.txt
我的Results2.txt
文件如下所示。
45008657|a.long|0
49210987|a.steven|3262
49600694|a.steven|4772
467814|a.rafealnadal|4133
53111047|a.miketyson|13484
Results.txt
有什么方法可以在我的初始文件 ( ) 本身中完成上述所有步骤吗?我想减少文件的过度使用,以便后期调试很容易。
编辑:我只是不想在创建新文件后删除一次文件,这对我来说似乎不是一个优雅的解决方案。
答案1
使用 GNU sed
:
sed -i 's/\s//g;s/\(|[^|]*\)|\([^|]*\)|/\1\2/;s/.*/\L&/' Results.txt
答案2
事实上,您不需要临时文件。
awk -F'|' '{gsub("[ \t\r]", "", $0)}{print $1,tolower($2$3$4),$5}' OFS='|' inputfile
表达式的第一部分执行您使用 执行的操作tr
。第二部分将字段 2-4 合并并将其小写并与其他两个字段一起打印。
对于您的输入,它会产生:
45008657|a.long|0
49210987|a.steven|3262
49600694|a.steven|4772
467814|a.rafealnadal|4133
53111047|a.miketyson|13484
GNU awk 4.1.0 及更高版本支持就地编辑。你可以说:
awk -i inplace -F'|' '{gsub("[ \t\r]", "", $0)}{print $1,tolower($2$3$4),$5}' OFS='|' inputfile
答案3
根据您最初的尝试,如果您使用该实用程序,则可以将所有命令放在同一个管道中sponge
:
cat Results.txt |
tr -d " \t\r" |
awk 'BEGIN { FS = "|" } ;
{ print $1"|"tolower($2) tolower($3) tolower($4)"|"$5 }' |
sponge Results.txt
sponge
将其存储stdin
在内存中,直到到达输入末尾,然后写入文件。对于上述大小的文件来说,这应该是可以接受的。
请注意,您还可以使用 shell 重定向来输入文件而td
不是cat
,例如:
tr -d " \t\r" <Results.txt
答案4
只需使用允许就地编辑的工具即可。以 Perl 为例:
perl -i -F'\|' -lane 's/[ \t]+//g for @F; print lc("$F[0]|$F[1]$F[2]$F[3]|$F[4]")' a
打开
-i
in-plcae 编辑,更改将直接应用于原始文件(换句话说,perl
处理创建和删除临时文件)。打开
-a
对给定字符的自动分割-F
,字段保存在数组中@F
。删除
s/[ \t]+//g
所有空格和制表符,并使lc()
所有内容变为小写。