我正在尝试编写一个反转输入行的实用程序。以下只是按原样打印行:
#!/bin/sed -f
#insert newline at the beginning
s/^/\n/
#while the newline hasnt moved to the end of pattern space, rotate
: loop
/\n$/{!s/\(.*\)\(.$\)/\2\1/;!b loop}
#delete the newline
s/\n//
关于什么是错的任何想法?
答案 0 :(得分:5)
/\n$/{!s/\(.*\)\(.$\)/\2\1/;!b loop}
!
位于地址/范围normaly !b
(不是goto ,如果我强调你的意思)可能是t
(如果发生替换,请转到)$
不属于最后一组,只是在所以这一行是:
/\n$/ !{s/\(.*\)\(.\)$/\2\1/;t loop}
现在,这个代码只是(在最后)没有做任何事情,它在开始时添加一个新行,并通过交换最后一个字符并且不反对任何东西将其移动到最后。
sed 'G
:loop
s/\(.\)\(\n.*\)/\2\1/
t loop
s/.//' YourFile
应该做的伎俩
@TobySpeight仍然增强了代码,无需第一组(代码改编)
答案 1 :(得分:1)
$ echo -e '123\n456\n789' |sed -nr '/\n/!G;s/(.)(.*\n)/&\2\1/;/^\n/!D;s/\n//p'
321
654
987
核心理念:
D
命令来模拟一个循环; sed
每次处理一行;但是我们可以使用s
和D
命令来模拟一行的循环。flag char
来识别每行的结尾,\n
是完美的选择。D
命令每次\n
删除chars util pattern space
,
然后强制sed
跳转到它的第一个命令,这实际上是一个循环!所以我们还需要在最终字符串之前添加一些无用的placeholder
以便D
命令删除,我们可以在current line
\n
之前使用\n
中的内容还包括)。说明:
/\n/!G
:如果当前pattern space
包含\n
,则表示此命令处于一行处理中;否则,使用G
命令将\n
和hold space
附加到pattern space
(sed
将删除每行的\n
,然后再将其放入pattern space
),pattern space
命令之后G
的内容是原始内容和\n
。s/(.)(.*\n)/&\2\1/;
:使用s
命令删除第一个字符(util \n
),然后在最终字符串后插入。/^\n/!D;s/\n//p
:如果当前pattern space
以\n
开头,这意味着此行已经解决,请使用s/\n//p
删除flag char: \n
并打印最后的字符串;否则使用D
命令删除useless placeholder
,然后跳转到第一个命令来处理第二个字符... 要进行摘要,循环中pattern space
中的内容如下所示:
123\n [(1)(23\n)] =s=> 123\n23\n1 [(123\n)(23\n)(1)] =D=> 23\n1
23\n1 [(2)(3\n)1] =s=> 23\n3\n21 [(23\n)(3\n)(2)1] =D=> 3\n21
3\n21 [(3)(\n)21] =s=> 3\n\n321 [(3\n)(\n)(3)21] =D=> \n321
\n321 [()(\n)321] =s=> \n321 =!D=> \n321 =s-p=> 321
有一些派生的解决方案:
placeholder
可以设置另一个以\n
结尾的字符串:$ echo -e '123\n456\n789' |sed -nr '/\n/!G;s/(.)(.*\n)/USELESS\n\2\1/;/^\n/!D;s/\n//p'
321
654
987
D
命令$ echo -e '123\n456\n789' |sed -nr '/\n/!G;s/(.)(.*\n)/&\2\1/;Tend;D;:end;s/\n//p'
321
654
987
.
获取第一个字符\n
$ echo -e '123\n456\n789' |sed -nr '/\n/!G;s/(.)(.*\n)/&\2\1/;/^\n/!D;s/.//p'
321
654
987
$ echo -e '123\n456\n789' |sed -nr ':loop;/\n/!G;s/(.)(.*\n)/\2\1/;tloop;s/.//p'
321
654
987
此解决方案更容易理解,pattern space
res中的内容如下所示:
123\n [(1)(23\n)] =s=> 23\n1 [(23\n)(1)]
23\n1 [(2)(3\n)1] =s=> 3\n21 [(3\n)(2)1]
3\n21 [(3)(\n)21] =s=> \n321 [(\n)(3)21]
\n321 [()(\n)321] =s=> \n321 =s=> 321
答案 2 :(得分:0)
问题是你正在使用错误的工具来尝试理解/使用在1970年代中期发明awk时已经过时的结构。
$ cat file
tsuj
esu
na
etaorporppa
loot
$ awk -v FS= '{rev=""; for (i=1; i<=NF; i++) rev = $i rev; print rev}' file
just
use
an
approproate
tool