我希望能够做到以下几点:
String1= "HELLO 3002_3322 3.2.1.log"
输出如下:
output = "3002_3322 3.2.1.log HELLO"
我知道命令sed能够做到这一点,但我需要一些指导。
谢谢!
答案 0 :(得分:4)
<强> AWK 强>
awk
是一个做同样事情的工具:
echo "HELLO 3002_3322 3.2.1.log" | awk '{print $2$3" "$1}'
它的作用:
awk
,没有-F
的分隔符标记按空格序列分割<强> SED 强>
我有一个看起来不合适的sed
示例:
echo "HELLO 3002_3322 3.2.1.log" | sed 's_\(.*\)\s\(.*\)\s\(.*\)_\3 \2 \1_'
它的作用:
s_<pattern>_<replacement>_
s
代表替代.*
表示匹配任何字符序列或根本不匹配任何字符。暂时忽略\
(
和)
\s
。 \s
匹配一个空格。所以,我们要求sed将(.*)\s
- 即() (
是sed中的特殊字符。所以我们必须通过正斜杠来逃避它。因此,(.*)\s(.*)\s(.*)
变为\(.*\)\s\(.*\)\s\(.*\)
。哦,真漂亮!
答案 1 :(得分:3)
在sed中你可以这样做:
sed 's/\([^[:blank:]]*\)[[:blank:]]*\(.*\)/\2 \1/'
哪个输出3002_3322 3.2.1.log HELLO
。
<强>解释强>
\([^[:blank:]]*\)
\(\)
表示我想捕获此组以便稍后使用。 [:blank:]
是用于空白字符的POSIX字符类。您可以在此处查看其他POSIX字符类:http://www.regular-expressions.info/posixbrackets.html
外部[]
表示匹配任何字符,^
表示除字符类中列出的字符外的任何字符。最后,*
表示前一个字符的任意出现次数(包括0)。所以总共[^[:blank:]]*
这意味着匹配一组不是空白的字符或第一个字。我们必须做这个有点复杂的正则表达式,因为POSIX sed只支持贪婪匹配的BRE(基本正则表达式),并找到我们想要非贪婪匹配的第一个单词。
[[:blank:]]*
,如上所述,这意味着匹配一组连续的空格。
\(.*\)
这意味着捕获剩下的行。 .
表示任何单个字符,因此与*
结合使用意味着匹配其余字符。
对于替换,\2 \1
表示替换我们与第二个捕获组匹配的模式,一个空格,然后替换第一个捕获组。
答案 2 :(得分:1)
这可能适合你(GNU sed):
SELECT * FROM <table> EXCEPT TOP 50 PERCENT...;
模式匹配非空格,空格和剩下的内容,然后在替换命令的替换部分中使用记忆模式(后引用)。
N.B。 sed -r 's/^(\S+)(\s+)(.*)/\3\2\1/' file
aurgument只是删除了对copius反斜杠的需要,所以相同的解决方案可以写成:
-r
这也消除了元字符sed 's/^\(\S\S*\)\(\s\s*\)\(.*\)/\3\2\1/' file
的合成糖,这意味着一种或多种先前的模式。
进一步注意,+
和\S
可能分别由\s
和[^[:space:]]
取代。导致:
[[:space:]]
答案 3 :(得分:1)
你也可以这样做(没有awk或sed):
#!/bin/sh
String1="HELLO 3002_3322 3.2.1.log"
start="${String1%% *}"
end="${String1#* }"
output="$end $start"
echo "$output"
或使用cut
(在Bash中):
#!/bin/bash
String1="HELLO 3002_3322 3.2.1.log"
rstr="$(echo "$String1" |cut -d" " -f1)"
output="${String1/$rstr /} $rstr"
echo "$output"