如何从字符串中剪切字符并将其放在最后 - 在shell中

时间:2015-06-03 04:21:28

标签: linux shell sed

我希望能够做到以下几点:

String1= "HELLO 3002_3322 3.2.1.log"

输出如下:

output = "3002_3322 3.2.1.log HELLO"

我知道命令sed能够做到这一点,但我需要一些指导。

谢谢!

4 个答案:

答案 0 :(得分:4)

<强> AWK

awk是一个做同样事情的工具:

echo "HELLO 3002_3322 3.2.1.log" | awk '{print $2$3" "$1}'

它的作用:

  • awk,没有-F的分隔符标记按空格序列分割
  • 这意味着,将会看到HELLO 3002_3322和3.2.1.log
  • HELLO是1美元;
  • 3002_3322是2美元,依此类推
  • 我们打印$ 2,然后$ 3然后一个空格,然后$ 1

<强> SED

我有一个看起来不合适的sed示例:

echo "HELLO 3002_3322 3.2.1.log" | sed 's_\(.*\)\s\(.*\)\s\(.*\)_\3 \2 \1_'

它的作用:

  • 命名法是s_<pattern>_<replacement>_
  • 首先s代表替代
  • _是分隔符
  • (。*)是paranthesis dot star括号。这是我们要求匹配的第一组角色。 .*表示匹配任何字符序列或根本不匹配任何字符。暂时忽略\ ()
  • 注意组之后的\s\s匹配一个空格。所以,我们要求sed将(.*)\s - 即()
  • 分开
  • 我们重复一遍告诉sed - (group1)(group2)(group3)
  • 第一组的简写是\ 1,group2的简写是\ 2等。
  • 为了替换,我们告诉sed首先安排\ 3(group3),然后是\ 2(group2)然后\ 1(group1)

(是sed中的特殊字符。所以我们必须通过正斜杠来逃避它。因此,(.*)\s(.*)\s(.*)变为\(.*\)\s\(.*\)\s\(.*\)。哦,真漂亮!

答案 1 :(得分:3)

在sed中你可以这样做:

sed 's/\([^[:blank:]]*\)[[:blank:]]*\(.*\)/\2 \1/'

哪个输出3002_3322 3.2.1.log HELLO

<强>解释

  1. 第一个单词被捕获 \([^[:blank:]]*\) \(\)表示我想捕获此组以便稍后使用。 [:blank:]是用于空白字符的POSIX字符类。您可以在此处查看其他POSIX字符类:
  2. http://www.regular-expressions.info/posixbrackets.html

    外部[]表示匹配任何字符,^表示除字符类中列出的字符外的任何字符。最后,*表示前一个字符的任意出现次数(包括0)。所以总共[^[:blank:]]*这意味着匹配一组不是空白的字符或第一个字。我们必须做这个有点复杂的正则表达式,因为POSIX sed只支持贪婪匹配的BRE(基本正则表达式),并找到我们想要非贪婪匹配的第一个单词。

    1. [[:blank:]]*,如上所述,这意味着匹配一组连续的空格。

    2. \(.*\)这意味着捕获剩下的行。 .表示任何单个字符,因此与*结合使用意味着匹配其余字符。

    3. 对于替换,\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"