特定于行的awk单词重新排序

时间:2018-05-09 10:06:17

标签: string awk pattern-matching

假设一个包含两种交替类型的行的多行文本文件。第一行以“>”开头并包含由下划线分隔的字母数字字符串。第二行由单个字母数字字符串组成。

$ cat file
>foo_bar_baz1
abcdefghijklmnopqrstuvwxyz0123456789
>foo_bar_baz2
abcdefghijklmnopqrstuvwxyz0123456789
>foo_bar_baz3
abcdefghijklmnopqrstuvwxyz0123456789

我想更改以“>”开头的那些字词的顺序。

$ cat file | sought_command
>baz1_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz2_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz3_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789

我知道可以使用 awk 完成此任务。

我如何更改以下草稿 awk 代码以实现我的目标?在目前的形式中,下面的代码只打印以“>”开头的行,但不打印那些没有。

的行
awk -F'_' '$1 ~ /^>/ { print ">"$3"_"$1"_"$2}' file | sed 's/>foo/foo/'
>baz1_foo_bar
>baz2_foo_bar
>baz3_foo_bar

2 个答案:

答案 0 :(得分:1)

这是一种方式。 1将打印所有行,而只修改所需的行:

$ awk -F'_' '$1 ~ /^>/ {$0 = ">"$3"_"$1"_"$2}1' file | sed 's/>foo/foo/'
>baz1_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz2_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz3_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789

您可能更喜欢使用substr而不是sed来管道:

$ awk -F'_' '$1 ~ /^>/ { $0 = ">" $3 "_" substr($1,2) "_" $2}1' file
>baz1_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz2_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789
>baz3_foo_bar
abcdefghijklmnopqrstuvwxyz0123456789

答案 1 :(得分:1)

关注awk可以帮助您在Input_file中的>行中处理N个字段。

awk '/^>/{sub(/>/,"");num=split($0,a,"_");for(i=num;i>=1;i--){val=val?val OFS a[i]:a[i]};print ">"val;val="";next} 1' OFS="_"  Input_file

现在也添加非单线形式的解决方案。

awk '
/^>/{
  sub(/>/,"");
  num=split($0,a,"_");
  for(i=num;i>=1;i--){  val=val?val OFS a[i]:a[i]  };
  print ">"val;
  val="";
  next}
1
' OFS="_"   Input_file