求取一行文本文件
Resort a Row of textfile
computer0-1 computer0-2 computer0-3
computer0-10 computer0-5 computer0-6
computer0-2 computer0-7 computer0-3
这些保存在文本文件中。我想编写一个 bash 脚本来检查每一行:
如果该行包含computer0-1
,则在行首写另一个computer0-1
。例如:
computer 0-1 computer0-10 computer0-5 computer0-1.
如果该行包含computer0-7
,则在行首写另一个computer0-7
。
如果该行包含computer0-10
,则在行首写另一个computer0-10
。
我尝试使用 if 和 for 循环,但我不知道如何正确编写它们。
我需要编写一个脚本来执行此操作,我是 Linux 的新手。我怎样才能做到这一点?有简单的方法吗?
使用 sed :
sed -e 's/^.*\b\(computer0-1\)\b/\t[=10=]/' -e 's/^.*\b\(computer0-10\)\b/\t[=10=]/' -e 's/^.*\b\(computer0-7\)\b/\t[=10=]/' <file>
它在行中搜索 computer0-1
、computer0-10
、computer0-7
之一,如果找到,则将其副本放在行的开头,然后是表格以及该行的其余部分。
详细解释:
s/<search>/<replace>/ replaces the <search>ed pattern with the <replace> expression
^ matches the start of the line
.* matches everything until the next pattern matches
\b is the word-boundary metacharacter : it matches the start and end of a word of [a-zA-Z_] characters
\(...\) groups a fragment of pattern. We can reference it later.
is a back-reference to the first (and only) group defined earlier
[=11=] is a back-reference to the whole matched string
所以我们所做的是匹配搜索到的标记(即 computer0-1),同时确保它是一个完整的单词(computer0-1 不应该匹配 computer0-12),然后我们通过追加重新创建匹配的字符串它到匹配的令牌。
测试运行:
$ echo """computer0-1 computer0-2 computer0-3
> computer0-10 computer0-5 computer0-6
> computer0-2 computer0-7 computer0-3""" > input
$ sed -e 's/^.*\b\(computer0-1\)\b/\t[=12=]/' -e 's/^.*\b\(computer0-10\)\b/\t[=12=]/' -e 's/^.*\b\(computer0-7\)\b/\t[=12=]/' input
computer0-1 computer0-1 computer0-2 computer0-3
computer0-10 computer0-10 computer0-5 computer0-6
computer0-7 computer0-2 computer0-7 computer0-3
awk
救援!
$ awk '{for(i=1;i<=NF;i++) if($i~/computer0-(1|10|7)$/) print $i, [=10=]}' file | column -t
computer0-1 computer0-1 computer0-2 computer0-3
computer0-10 computer0-10 computer0-5 computer0-6
computer0-7 computer0-2 computer0-7 computer0-3
请注意,此搜索是按字段顺序进行的,将打印第一个匹配项。如果键的优先级很重要(如果 -1 和 -10 在同一行匹配,总是使用 -1)你可以使用这个
$ awk 'BEGIN{pre="computer0-"; p[1]=pre"1 "; p[2]=pre"10"; p[3]=pre"7"}
{for(i=1;i<4;i++)
if([=11=]~p[i])
{print p[i], [=11=];
next}
}' file | column -t
computer0-1 computer0-2 computer0-3
computer0-10 computer0-5 computer0-6
computer0-2 computer0-7 computer0-3
这些保存在文本文件中。我想编写一个 bash 脚本来检查每一行:
如果该行包含
computer0-1
,则在行首写另一个computer0-1
。例如:computer 0-1 computer0-10 computer0-5 computer0-1.
如果该行包含
computer0-7
,则在行首写另一个computer0-7
。如果该行包含
computer0-10
,则在行首写另一个computer0-10
。
我尝试使用 if 和 for 循环,但我不知道如何正确编写它们。
我需要编写一个脚本来执行此操作,我是 Linux 的新手。我怎样才能做到这一点?有简单的方法吗?
使用 sed :
sed -e 's/^.*\b\(computer0-1\)\b/\t[=10=]/' -e 's/^.*\b\(computer0-10\)\b/\t[=10=]/' -e 's/^.*\b\(computer0-7\)\b/\t[=10=]/' <file>
它在行中搜索 computer0-1
、computer0-10
、computer0-7
之一,如果找到,则将其副本放在行的开头,然后是表格以及该行的其余部分。
详细解释:
s/<search>/<replace>/ replaces the <search>ed pattern with the <replace> expression
^ matches the start of the line
.* matches everything until the next pattern matches
\b is the word-boundary metacharacter : it matches the start and end of a word of [a-zA-Z_] characters
\(...\) groups a fragment of pattern. We can reference it later.
is a back-reference to the first (and only) group defined earlier
[=11=] is a back-reference to the whole matched string
所以我们所做的是匹配搜索到的标记(即 computer0-1),同时确保它是一个完整的单词(computer0-1 不应该匹配 computer0-12),然后我们通过追加重新创建匹配的字符串它到匹配的令牌。
测试运行:
$ echo """computer0-1 computer0-2 computer0-3
> computer0-10 computer0-5 computer0-6
> computer0-2 computer0-7 computer0-3""" > input
$ sed -e 's/^.*\b\(computer0-1\)\b/\t[=12=]/' -e 's/^.*\b\(computer0-10\)\b/\t[=12=]/' -e 's/^.*\b\(computer0-7\)\b/\t[=12=]/' input
computer0-1 computer0-1 computer0-2 computer0-3
computer0-10 computer0-10 computer0-5 computer0-6
computer0-7 computer0-2 computer0-7 computer0-3
awk
救援!
$ awk '{for(i=1;i<=NF;i++) if($i~/computer0-(1|10|7)$/) print $i, [=10=]}' file | column -t
computer0-1 computer0-1 computer0-2 computer0-3
computer0-10 computer0-10 computer0-5 computer0-6
computer0-7 computer0-2 computer0-7 computer0-3
请注意,此搜索是按字段顺序进行的,将打印第一个匹配项。如果键的优先级很重要(如果 -1 和 -10 在同一行匹配,总是使用 -1)你可以使用这个
$ awk 'BEGIN{pre="computer0-"; p[1]=pre"1 "; p[2]=pre"10"; p[3]=pre"7"}
{for(i=1;i<4;i++)
if([=11=]~p[i])
{print p[i], [=11=];
next}
}' file | column -t