我收到了一份文件。如果一行有" xxx"作为第三个词,我需要用" yyy"替换它。我的最终输出必须包含修改后的所有原始行。 输入文件是 -
abc xyz mno
xxx xyz abc
abc xyz xxx
abc xxx xxx xxx
所需的输出文件应为 -
abc xyz mno
xxx xyz abc
abc xyz yyy
abc xxx yyy xxx
我试过了 -
grep "\bxxx\b" file.txt | awk '{if ($3=="xxx") print $0;}' | sed -e 's/[^ ]*[^ ]/yyy/3'
但这会将输出显示为 -
abc xyz yyy
abc xxx yyy xxx
答案 0 :(得分:2)
以下简单的awk
可能对您有帮助。
awk '$3=="xxx"{$3="yyy"} 1' Input_file
输出如下。
abc xyz mno
xxx xyz abc
abc xyz yyy
abc xxx yyy xxx
说明: 如果$3
第3个字段等于字符串xxx
,则将检查条件设置为$3
,然后将yyy
的值设置为字符串1
。然后在那里提到awk
,因为1
适用于条件方法然后操作。我在这里通过提及class LoadListView(ListView):
# ...
def get_context_data(self, **kwargs):
context = super(LoadListView, self).get_context_data(**kwargs)
statuses = (choice[0] for choice in Load.LOAD_STATUS_CHOICES)
context['loads_by_status'] = {
status: Load.objects.filter(load_status=status) for status in statuses
}
return context
并且没有提及任何动作来使条件为TRUE,因此当前行的默认打印将发生(无论是更改的第3个字段还是新的第3个字段)。
答案 1 :(得分:1)
sed
解决方案:
sed -E 's/^(([^[:space:]]+[[:space:]]+){2})apathy\>/\1empathy/' file
输出:
abc xyz mno
apathy xyz abc
abc xyz empathy
abc apathy empathy apathy
修改文件 inplace 添加-i
选项:sed -Ei ....
答案 2 :(得分:0)
通常,awk
命令可能看起来像
awk '{command set 1}condition{command set 2}' file
如果前面的条件为真,则会为每一行执行command set 1
,而command set 2
将被执行。
我的最终输出必须包含修改后的所有原始行 线
在你的情况下
awk 'BEGIN{print "Original File";i=1}
{print}
$3=="xxx"{$3="yyy"}
{rec[i++]=$0}
END{print "Modified File";for(i=1;i<=NR;i++)print rec[i]}'file
应该解决这个问题。
<强>解释强>
$3
是awk
中第三个以空格分隔的字段。如果它与"xxx"
匹配,则替换它。首先打印未修改的行,同时将修改的行存储在数组中。最后,打印修改后的线条。 BEGIN
和END
块仅分别在开头和结尾执行。 NR
是awk内置变量,表示直到当时处理的记录数。由于它在END
块中使用,因此它应该为我们提供记录总数。
所有好: - )
答案 3 :(得分:0)
Ravinder已经为您提供了最短的awk解决方案。
在sed中,以下内容可行:
sed -E 's/(([^ ]+ ){2})xxx/\1yyy/'
或者,如果您的sed不包含-E
,您可以使用更痛苦的BRE表示法:
sed 's/\(\([^ ][^ ]* \)\{2\}\)xxx/\1yyy/'
如果你有兴趣单独用bash处理这个问题,那么这样的事情可能有用:
while read -r line; do
read -r -a a <<<"$line"
[[ "${a[2]}" == "xxx" ]] && a[2]="yyy"
printf '%s ' "${a[@]}"
printf '\n'
done < input.txt