Linux 如何从字符串中剪切字符并将其放在shell的末尾

Linux 如何从字符串中剪切字符并将其放在shell的末尾,linux,shell,sed,Linux,Shell,Sed,我希望能够做到以下几点: String1= "HELLO 3002_3322 3.2.1.log" 并获得如下输出: output = "3002_3322 3.2.1.log HELLO" 我知道sed司令部能做到这一点,但我需要一些指导 谢谢 AWK awk是一种执行类似操作的工具: echo "HELLO 3002_3322 3.2.1.log" | awk '{print $2$3" "$1}' 它的作用是: awk,不带分隔符标志的-F按空格序列分割 也就是说,将看到HELLO

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

String1= "HELLO 3002_3322 3.2.1.log"
并获得如下输出:

output = "3002_3322 3.2.1.log HELLO"
我知道sed司令部能做到这一点,但我需要一些指导

谢谢

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\uuuuuuu
  • 第一个
    s
    代表替换
  • _是分隔符
  • (*)是点星括号。这是我们要求sed匹配的第一组字符
    *
    表示匹配任意字符序列或完全不匹配字符。暂时忽略
    之前的
    \
  • 请注意组后面的
    \s
    <代码>\s匹配一个空格。因此,我们要求sed将
    (.*)\s
    -即()
  • 我们重复这一点来告诉sed-(第1组)(第2组)(第3组)
  • 第一组的速记是\1,第二组的速记是\2,以此类推
  • 对于替换,我们告诉sed先安排\3(组3),然后安排\2(组2),然后安排\1(组1)
在sed中是一个特殊字符。因此我们必须用正斜杠对其进行转义。因此,
(.*)s(.*)s(.*)
变为
\(.*)\s\(.*)\s\(.*)
。哦,太漂亮了!

在sed中,您可以做:

sed 's/\([^[:blank:]]*\)[[:blank:]]*\(.*\)/\2 \1/'
输出
3002_3322 3.2.1.log HELLO

解释

  • 第一个单词由
    \([^[:blank:][]*\)
    \(\)
    表示我想捕获此组以供以后使用。
    [:blank://code>是一个用于空格字符的POSIX字符类。您可以在此处看到其他POSIX字符类:
  • 外部
    []
    表示匹配任何字符,而
    ^
    表示除字符类中列出的字符以外的任何字符。最后
    *
    表示前一个字符的任何出现次数(包括0)。因此总共
    [^[:blank:]*
    这意味着匹配一组非空白字符或第一个单词。我们必须执行这项有点复杂的正则表达式,因为POSIX sed只支持贪婪匹配的BRE(基本正则表达式),而要找到我们想要的非贪婪匹配的第一个单词

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

  • \(.*)
    这表示捕获行的其余部分。
    表示任何单个字符,因此与
    *
    组合表示匹配其余字符

  • 对于替换,
    \2\1
    意味着替换我们与第二个捕获组(一个空格)匹配的模式,然后是第一个捕获组

  • 这可能适用于您(GNU-sed):

    模式匹配非空格、空格和剩余的内容,然后在替换命令的替换部分使用记住的模式(反向引用)

    注意,
    -r
    aurgument只是消除了对复印机背面斜杠的需要,因此相同的解决方案可以写成:

    sed 's/^\(\S\S*\)\(\s\s*\)\(.*\)/\3\2\1/' file
    
    这也去除了元字符
    +
    的句法糖分,这意味着一个或多个前面的模式

    进一步注意,
    \S
    \S
    可分别替换为
    [^[:space:]]
    [:space:]
    。导致:

    sed 's/^\([^[:space:]][^[:space:]]*\)\([[:space:]][[:space:]]*\)\(.*\)/\3\2\1/' file
    
    您也可以这样做(无需awk或sed):

    或者使用
    cut
    (在Bash中):


    您需要知道如何在sed中执行此操作?是否只希望将“HELLO”移到末尾?提供更多详细信息并显示您的尝试。请注意,POSIX sed不支持\s,您应该使用[[:blank:]为了表示空白字符。在这里,
    ^
    $
    是可选的谢谢!这起作用了。你能详细说明一下组和语法吗。据我所知,第一组一直保留到第一个空格吗?但对第二组,特别是:blank:part,不太确定。我添加了更多解释n、 希望这能有所帮助。
    sed 's/^\([^[:space:]][^[:space:]]*\)\([[:space:]][[:space:]]*\)\(.*\)/\3\2\1/' file
    
    #!/bin/sh
    String1="HELLO 3002_3322 3.2.1.log"
    start="${String1%% *}"
    end="${String1#* }"
    output="$end $start"
    echo "$output"
    
    #!/bin/bash
    String1="HELLO 3002_3322 3.2.1.log"
    rstr="$(echo "$String1" |cut -d" " -f1)"
    output="${String1/$rstr /} $rstr"
    echo "$output"