我有一个文件(filename.txt
),结构如下:
>line1
ABC
>line2
DEF
>line3
GHI
>line4
JKL
我想将不启动机智>
的字符串中的字符洗牌。输出(例如)如下所示:
>line1
BCA
>line2
DFE
>line3
IHG
>line4
KLJ
这就是我试图将字符串中的字符混洗:sed 's/./&\n/' | shuf | tr -d "\n"
。看起来它有效,但它没有考虑换行。此外,它对所有数据执行命令,而不仅对不以>
开头的行执行命令。
答案 0 :(得分:3)
使用perl
和ruby
$ # split// to get individual characters
$ # join "" to join characters with empty string
$ # if !/^>/ to apply the change only for lines not starting with >
$ # alternate: perl -MList::Util=shuffle -lne 'print /^>/ ? $_ : shuffle split//'
$ perl -MList::Util=shuffle -lpe '$_=join "", shuffle split// if !/^>/' ip.txt
>line1
CBA
>line2
FED
>line3
IHG
>line4
JKL
$ # $_.chars to get individual characters
$ # * "" to join array elements with empty string
$ ruby -lpe '$_ = $_.chars.shuffle * "" if !/^>/' ip.txt
>line1
BAC
>line2
EDF
>line3
GHI
>line4
JKL
答案 1 :(得分:3)
awk
+ coreutils
方法:
awk '/^[^>]/{ system("echo "$1"| fold -w1 | shuf | tr -d \047\n\047"); print ""; next }1' file
示例输出:
>line1
BAC
>line2
EDF
>line3
HGI
>line4
KLJ
答案 2 :(得分:2)
GNU sed
:
$ cat filename.txt
>line1
ABC
>line2
DEF
>line3
GHI
>line4
JKL
$ sed -r "/^[^>]/s/.*/grep -o . <<< & |sort -R |tr -d '\n'/e" filename.txt
>line1
ABC
>line2
FDE
>line3
HGI
>line4
LKJ
$ sed -r "/^[^>]/s/.*/grep -o . <<< & |shuf |tr -d '\n'/e" filename.txt
>line1
BCA
>line2
FDE
>line3
HIG
>line4
JKL
编辑:sed
在所有(GNU sed) 4.2.2
上都运行相同,我们可以通过删除e
修饰符来打印由sed生成的原始命令字符串:
sed -r '/^[^>]/s/.*/grep -o . <<< & |shuf |tr -d "\n"/' filename.txt
>line1
grep -o . <<< ABC |shuf |tr -d "
"
>line2
grep -o . <<< DEF |shuf |tr -d "
"
>line3
grep -o . <<< GHI |shuf |tr -d "
"
>line4
grep -o . <<< JKL |shuf |tr -d "
"
然后,e
的{{1}}命令的s
修饰符将调用sed
来执行它。 sh
上的sh
是指向CentOS
的符号链接,但在Ubuntu上,它是指向bash
的符号链接,而dash
可能不支持dash
(<<<
)。
here-string
所以,我需要修改我的答案,为# on Ubuntu, enter into sh terminal:
$ grep -o . <<< JKL |shuf |tr -d '\n'
sh: 2: Syntax error: redirection unexpected
$ echo JKL |grep -o . |shuf |tr -d '\n'
KLJ
和bash
工作:
dash
简单解释:
$ sed -r '/^[^>]/s/.*/echo -n & |grep -o . |shuf |tr -d "\n"/e' filename.txt
>line1
ACB
>line2
DFE
>line3
IHG
>line4
LJK
:强制/^[^>]/
处理以sed
(^
)开头的行(>
)。[^>]
:s/.*/echo -n & |grep -o . |shuf |tr -d "\n"/
是整行,使用.*
来替换它,因此&
是整个原始行,然后生成一个普通的命令字符串{ {1}},可以改变界限。&
命令的echo -n ORIGIN_LINE |grep -o . |shuf |tr -d "\n"
修饰符来执行上面生成的普通命令字符串。 答案 3 :(得分:1)
这是GNU awk中的一个:
basicSalary
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed '/^>/b;s/./&\n/g;s/.$//;s/.*/echo "&"|shuf/e' file
打印以>
开头但不处理的行。否则,在当前行中的每个字符之间插入换行符,并删除最后一个不需要的换行符。然后echo
生成文件并通过shuf
命令管道(如果需要,可以替换排序-R)并打印结果。
N.B。此解决方案在替换命令上使用GNU特定的e
标志,但结果可以传递给shell,如下所示:
sed '/^>/s/.*/echo "&"/;t;s/./&\n/g;s/.$//;s/.*/echo "&"|shuf/' file | sh