我有一个长度为5个字符的字符串列表。将每行的第一,第三和第五个字符(包括空格)转换为单个字符串的最佳方法是什么?
输入:
[Unit]
Description=Advanced key-value store
After=network.target
Documentation=http://redis.io/documentation, man:redis-server(1)
[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
ExecStop=/bin/kill -s TERM $MAINPID
PIDFile=/var/run/redis/redis-server.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=2755
UMask=007
PrivateTmp=yes
LimitNOFILE=65535
PrivateDevices=yes
ProtectHome=yes
#Modified 20180129 to avoid issue to start redis
#redis-server.service: Failed at step NAMESPACE spawning /usr/bin/redis-server: Stale file handle
#ReadOnlyDirectories=/
ReadWriteDirectories=-/var/lib/redis
ReadWriteDirectories=-/var/log/redis
ReadWriteDirectories=-/var/run/redis
NoNewPrivileges=true
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
# redis-server can write to its own config file when in cluster mode so we
# permit writing there by default. If you are not using this feature, it is
# recommended that you replace the following lines with "ProtectSystem=full".
ProtectSystem=true
ReadWriteDirectories=-/etc/redis
[Install]
WantedBy=multi-user.target
Alias=redis.service
输出:
c c
8 8
4 4
3 3
1 1
4 4
9 9
8 | c
> 4
0 0
e | 5
6 | a
3 3
9 | c
b <
1 1
b | 0
d <
4 4
5 | 7
c c
> 3
. .
1 | c
o o
我使用sed捕获组取得了一些成功,但忽略了尾随空格。
c8431498 0e639b1bd45c .1o
c843149c405a3c 10 47c3.co
|> || |< | | > |
编辑:澄清我也需要包含空格,字符串包含一个点
答案 0 :(得分:4)
这是一个使用GNU awk并清空public class ClasssATest {
@Test
public void someTest() {
String input = "a string";
ExternalObject externalObject = Mockito.mock(ExternalObject.class);
Mockito.when(externalObject.parseString(eq(input))).thenReturn(externalObject);
ClassA sut = new ClassA(externalObject, input);
...
}
}
:
FS
答案 1 :(得分:4)
使用 GNU awk:
awk 'BEGIN{FS="";a="";b="";c="";}{a=a$1; b=b$3; c=c$5;}END{print a ORS c ORS b}' filename
输出:
c8431498 0e639b1bd45c
c843149c405a3c 10 47c3
|> || |< |< | >
答案 2 :(得分:4)
使用awk
awk内部变量的另一个不错的FIELDWITHS
解决方案:
FIELDWIDTHS A whitespace separated list of field widths. When set, gawk parses the input into fields of fixed width, instead of using the value of the FS variable as the field separa- tor. See Fields, above.
示例:
$ awk -v FIELDWIDTHS="1 1 1 1 1" '{b1=b1$1;b3=b3$3;b5=b5$5}END{print b1;print b5;print b3}' to_horizontal.txt
c8431498 0e639b1bd45c
c843149c405a3c 10 47c3
|> || |< |< | >
您可以使用FIELDWIDTHS
代替经典FS
来定义固定大小的列,这些列将在使用$1
,$2
后照常操作和访问, $3
,...
答案 3 :(得分:3)
我不知道使用sed
来解决这个问题,处理垂直列似乎非常复杂......所以,这里是使用cut/paste
的混搭的解决方案
$ # paste -s will convert all input lines into single line
$ # \0 delimiter means combine the lines with no character at all in between them
$ cut -c1 ip.txt | paste -sd'\0'
c8431498 0e639b1bd45c .1o
$ cut -c5 ip.txt | paste -sd'\0'
c843149c405a3c 10 47c3.co
$ cut -c3 ip.txt | paste -sd'\0'
|> || |< |< | > |
结合结果:
$ (cut -c1 ip.txt | paste -sd'\0'; cut -c5 ip.txt | paste -sd'\0'; cut -c3 ip.txt | paste -sd'\0') > f1
$ cat f1
c8431498 0e639b1bd45c .1o
c843149c405a3c 10 47c3.co
|> || |< |< | > |
$ # or use shell looping
$ for i in 1 5 3; do cut -c"$i" ip.txt | paste -sd'\0'; done
c8431498 0e639b1bd45c .1o
c843149c405a3c 10 47c3.co
|> || |< |< | > |
根据unix.stackexchange - paste files without delimiter,-d'\0'
由POSIX定义,适用于任何版本的paste
答案 4 :(得分:2)
这可能适合你(GNU sed):
sed -r '1s/^(.).(.).(.)$/\1\n\3\n\2/;:a;N;s/(\n.*)(\n.*)\n(.).(.).(.)/\3\1\5\2\4/;ta' file
在第一行后,在第1行,第3行和第1行之后添加换行符。第五个字符。在所有后续行中插入附加的行1st,3rd&amp;第5个字符。
N.B。输出请求交换最后两行,因此第3和第5个字符也被交换。