Bash 使用sed抓取特定文本并排序+;输入回文件

Bash 使用sed抓取特定文本并排序+;输入回文件,bash,sed,formatting,Bash,Sed,Formatting,我想请求一些帮助 我目前正在创建一个脚本,该脚本将有一个充满格式化文本的集合文件作为基础,然后根据用户输入从该文本文件中输入和删除。我会把这个放到bash脚本中 我已经找到了如何使用以下方法从文件中获取所需的文本: sed -n '/5.1.1"/,/|}/p' textfile.txt 5.1.1是我的服务器的机架位置,我正在抓取文件的文本,直到它找到|} 这将输出以下内容: |+ description = "5.1.1"; |- |1: ~servername~ [4U]; |- |5

我想请求一些帮助

我目前正在创建一个脚本,该脚本将有一个充满格式化文本的集合文件作为基础,然后根据用户输入从该文本文件中输入和删除。我会把这个放到bash脚本中

我已经找到了如何使用以下方法从文件中获取所需的文本:

sed -n '/5.1.1"/,/|}/p' textfile.txt
5.1.1是我的服务器的机架位置,我正在抓取文件的文本,直到它找到|}

这将输出以下内容:

|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername";
|-
|39: servername;
|-
|41: switch;
|}
以此类推,直到5.1.15

sed只选择我需要更改的文本

我的想法是,使用sed获取文本,插入需要的行,然后根据第二列中的数字对其进行排序,然后将修改后的文本重新插入到相同位置的文件中,但是我不知道如何实现这一点

我将要输入的行与其他行的格式相同,然后我将在它下面输出一个|-

多谢各位

编辑1:

因此,期望的输出是:

我有第16行:servername;我想输入rack 5.1.1中的这个文件

从上面取得基础的最终结果是:

|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|16: servername;
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername";
|-
|39: servername;
|-
|41: switch;
|}
编辑2:

我想我应该包括我写的用来格式化的脚本。它是不完整的,而且非常简陋,但是除了$location变量的if之外,它还起到了作用。为此,我需要修改正则表达式

#! /bin/bash


function serverread {

#Enter the location
function locationread { 
echo 'Enter the location of the server in the data center in format (x.x.x) ex. 5.1.15'
read location

if [[ "$location" =~ [0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2} ]]
then
          echo "Success"
  else
            echo "You have entered an incorrect format for the rack, please try again."
            locationread
            exit
fi
}
locationread

echo Please enter the rack space at which the server was placed
read rp

if (( $rp < 1 || $rp > 42));
then
        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
        read rp
else
{
        echo You entered: $rp as the server placement in the rack.
}
fi
#Enter the server name
echo Now please enter the server name "(Use ~ around the name if it is disconnected/unplugged)":
read name

if [[ $name == ~* ]] && [[ $name == *~ ]];
then
        echo "You entered: $name as the server name and it is currently disconnected in some way."
else
        echo "You entered: $name as the server name."
fi

#Enter the physical height of the server
echo Now please enter the size in height of the server:

function readsize {
read size
if [ $size -eq $size 2>/dev/null ]
then
        if (( $size < 1 || $size > 42));
        then
                echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
                readsize
        else
                echo "You entered: $size as the physical height of the server"
        fi
fi
}
readsize

#if (( $size == 1))
#
#  else
#                echo "$size is not an integer"
#        fi
#       
#if (( $size < 1 || $size > 42));
#then
#        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
#        read size
#else
#        echo "You entered: $size as the physical height of the server"
#fi

if (( $size == 1));
then
        echo Currently this is the line that will be entered: $rp": "$name";"
else
        echo Currently this is the line that will be entered: $rp": "$name" ["$size"U];"
fi
echo Is this correct? '[yes/no]'
read matrix
echo Would you like to add another server? '[yes/no]'
read matrix2

if (( $matrix == "yes" ));
then
        if (( $matrix2 == "yes" ));
                then
                        serverread
        else
                        echo This is complete
                exit
        fi
else
        echo Please run this command again
        exit
fi
}
serverread
这就是我将如何完成你在另一个文件中向我展示的脚本:

#! /bin/bash

export $(cat rackformat | grep -v ^# | xargs)
echo $finale

while IFS= read -r l; do 
        if [[ "$l" =~ description ]]; then            
                msg="$l"$'\n';                 
        elif [[ "$l" =~ "}" ]]; then                    
                { 
                        echo -n "$msg" | grep -v '|-'; 
                        echo "\|$finale"; 
                } | sed 's/^|//' | sort -n | sed 's/^/|/' | while IFS= read -r l; do 
                echo "$l"; 
                echo '|-'; 
        done | head -n-1; 
        echo '|}'; 
else 
        msg+="$l"$'\n'; 
fi; 
done
编辑4:

我没有包括上面的部分,因为我不认为这将是相关的,但我可能应该包括它,这是我的坏。这是输入之前的文本文件:

{| class="wikitable"
|
{| class="wikitable"
|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername~;
|-
|39: servername;
|-
|41: servername;
|}
|
{| class="wikitable"
这是当前脚本的输出:

{| class="wikitable"
|
{| class="wikitable"
|\|2.: test [2U];
|-
|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername~;
|-
|39: servername;
|-
|41: servername;
|}
|
{| class="wikitable"
#! /bin/bash


function serverread {

#Enter the location
function locationread {
echo 'Enter the location of the server in the data center in format (x.x.x) ex. 5.1.15'
read location

if [[ "$location" =~ [0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2} ]]
then
          echo "Success"
  else
            echo "You have entered an incorrect format for the rack, please try again."
            locationread
            exit
fi
}
locationread

function parser {
while IFS= read -r l; do 
        if [[ "$l" =~ description ]]; then            
                msg="$l"$'\n';                 
        elif [[ "$l" =~ "}" ]]; then                    
                { 
                        echo -n "$msg" | grep -v '|-'; 
                        echo "\|$finale"; 
                } | sed 's/^|//' | sort -n | sed 's/^/|/' | while IFS= read -r l; do 
                echo "$l"; 
                echo '|-'; 
        done | head -n-1; 
        echo '|}'; 
else 
        msg+="$l"$'\n'; 
fi; 
done
}

echo Please enter the rack space at which the server was placed
read rp

if (( $rp < 1 || $rp > 42));
then
        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
        read rp
else
{
        echo You entered: $rp as the server placement in the rack.
}
fi
#Enter the server name
echo Now please enter the server name "(Use ~ around the name if it is disconnected/unplugged)":
read name

if [[ $name == ~* ]] && [[ $name == *~ ]];
then
        echo "You entered: $name as the server name and it is currently disconnected in some way."
else
        echo "You entered: $name as the server name."
fi

#Enter the physical height of the server
echo Now please enter the size in height of the server:

function readsize {
read size
if [ $size -eq $size 2>/dev/null ]
then
        if (( $size < 1 || $size > 42));
        then
                echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
                readsize
        else
                echo "You entered: $size as the physical height of the server"
        fi
fi
}
readsize

#if (( $size == 1))
#
#  else
#                echo "$size is not an integer"
#        fi
#       
#if (( $size < 1 || $size > 42));
#then
#        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
#        read size
#else
#        echo "You entered: $size as the physical height of the server"
#fi

if (( $size == 1));
then
        echo Currently this is the line that will be entered: $rp": "$name";"
else
        echo Currently this is the line that will be entered: $rp": "$name" ["$size"U];"
fi

echo Is this correct? '[yes/no]'
read matrix
echo Would you like to add another server? '[yes/no]'
read matrix2

finale=$rp": "$name" ["$size"U];"
echo $finale

if (( $matrix == "yes" ));
then
        function b {
        # all text before 5.1.1
        sed -n '/'"$location"'"/q;p;' racktext.txt;
        # parse text in this section
        sed -n '/'"$location"'"/,/|}/p' racktext.txt | parser
        # all text below this section
        sed -n '/'"$location"'"/{ :a; /|}/{ n; :b; p; n; bb; }; n; ba; };' racktext.txt
        # use sponge to overwrite the file in a pipeline
        }
        b | sponge racktext.txt
        echo $
        if (( $matrix2 == "yes" ));
                then
                        serverread
        else
                        echo This is complete
        fi
else
        echo Please run this command again
        exit
fi
}
serverread
以下是当前脚本的全部内容:

{| class="wikitable"
|
{| class="wikitable"
|\|2.: test [2U];
|-
|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername~;
|-
|39: servername;
|-
|41: servername;
|}
|
{| class="wikitable"
#! /bin/bash


function serverread {

#Enter the location
function locationread {
echo 'Enter the location of the server in the data center in format (x.x.x) ex. 5.1.15'
read location

if [[ "$location" =~ [0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2} ]]
then
          echo "Success"
  else
            echo "You have entered an incorrect format for the rack, please try again."
            locationread
            exit
fi
}
locationread

function parser {
while IFS= read -r l; do 
        if [[ "$l" =~ description ]]; then            
                msg="$l"$'\n';                 
        elif [[ "$l" =~ "}" ]]; then                    
                { 
                        echo -n "$msg" | grep -v '|-'; 
                        echo "\|$finale"; 
                } | sed 's/^|//' | sort -n | sed 's/^/|/' | while IFS= read -r l; do 
                echo "$l"; 
                echo '|-'; 
        done | head -n-1; 
        echo '|}'; 
else 
        msg+="$l"$'\n'; 
fi; 
done
}

echo Please enter the rack space at which the server was placed
read rp

if (( $rp < 1 || $rp > 42));
then
        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
        read rp
else
{
        echo You entered: $rp as the server placement in the rack.
}
fi
#Enter the server name
echo Now please enter the server name "(Use ~ around the name if it is disconnected/unplugged)":
read name

if [[ $name == ~* ]] && [[ $name == *~ ]];
then
        echo "You entered: $name as the server name and it is currently disconnected in some way."
else
        echo "You entered: $name as the server name."
fi

#Enter the physical height of the server
echo Now please enter the size in height of the server:

function readsize {
read size
if [ $size -eq $size 2>/dev/null ]
then
        if (( $size < 1 || $size > 42));
        then
                echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
                readsize
        else
                echo "You entered: $size as the physical height of the server"
        fi
fi
}
readsize

#if (( $size == 1))
#
#  else
#                echo "$size is not an integer"
#        fi
#       
#if (( $size < 1 || $size > 42));
#then
#        echo You have entered an incorrect size for the server. Please enter a number between 1 and 42.
#        read size
#else
#        echo "You entered: $size as the physical height of the server"
#fi

if (( $size == 1));
then
        echo Currently this is the line that will be entered: $rp": "$name";"
else
        echo Currently this is the line that will be entered: $rp": "$name" ["$size"U];"
fi

echo Is this correct? '[yes/no]'
read matrix
echo Would you like to add another server? '[yes/no]'
read matrix2

finale=$rp": "$name" ["$size"U];"
echo $finale

if (( $matrix == "yes" ));
then
        function b {
        # all text before 5.1.1
        sed -n '/'"$location"'"/q;p;' racktext.txt;
        # parse text in this section
        sed -n '/'"$location"'"/,/|}/p' racktext.txt | parser
        # all text below this section
        sed -n '/'"$location"'"/{ :a; /|}/{ n; :b; p; n; bb; }; n; ba; };' racktext.txt
        # use sponge to overwrite the file in a pipeline
        }
        b | sponge racktext.txt
        echo $
        if (( $matrix2 == "yes" ));
                then
                        serverread
        else
                        echo This is complete
        fi
else
        echo Please run this command again
        exit
fi
}
serverread
#/bin/bash
函数serverread{
#输入位置
函数位置读取{
echo“以格式(x.x.x)例如5.1.15输入服务器在数据中心中的位置”
读取位置
如果[[“$location”=~[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}]]
然后
呼应“成功”
其他的
echo“您输入的机架格式不正确,请重试。”
位置读取
出口
fi
}
位置读取
函数分析器{
当IFS=read-rl;do时
如果[[“$l”=~说明]];则
msg=“$l”$”\n';
elif[[“$l”=~“}”];然后
{ 
echo-n“$msg”| grep-v'|-';
回声“\\\$finale”;
}| sed's/^ |/'| sort-n | sed's/^/|/'|而IFS=read-rl;do
回音“$l”;
回音“|-”;
完成|头-n-1;
回声“|}”;
其他的
msg+=“$l”$'\n';
fi;
完成
}
echo请输入放置服务器的机架空间
读rp
如果($rp<1 | |$rp>42));
然后
echo您为服务器输入的大小不正确。请输入一个介于1和42之间的数字。
读rp
其他的
{
您输入的echo:$rp作为机架中的服务器位置。
}
fi
#输入服务器名称
echo现在请输入服务器名称“(如果已断开连接/拔出,请在名称周围使用~1)”:
读名字
如果[[$name==~*]&&[$name===*~]];
然后
echo“您输入了:$name作为服务器名,它当前以某种方式断开连接。”
其他的
echo“您输入了:$name作为服务器名。”
fi
#输入服务器的物理高度
echo现在请输入服务器的高度大小:
函数读取大小{
读取大小
如果[$size-eq$size 2>/dev/null]
然后
如果($size<1 | |$size>42));
然后
echo您为服务器输入的大小不正确。请输入一个介于1和42之间的数字。
可读大小
其他的
echo“您输入:$size作为服务器的物理高度”
fi
fi
}
可读大小
#如果($size==1))
#
#否则
#echo“$size不是整数”
#fi
#       
#如果($size<1 | |$size>42));
#然后
#echo您为服务器输入的大小不正确。请输入一个介于1和42之间的数字。
#读取大小
#否则
#echo“您输入:$size作为服务器的物理高度”
#fi
如果($size==1));
然后
echo当前这是将要输入的行:$rp:“$name”
其他的
echo当前这是将要输入的行:$rp:“$name”[“$size”U];”
fi
“这对吗?”[是/否]'
读取矩阵
echo是否要添加其他服务器?“[是/否]'
读取矩阵2
结局=$rp:“$name”[“$size”U];”
echo$结局
如果($matrix==“是”);
然后
功能b{
#5.1.1之前的所有文本
sed-n'/'“$location””/q;p;'racktext.txt;
#分析本节中的文本
sed-n'/'“$location”“/,/|}/p'racktext.txt |解析器
#本节下面的所有文本
sed-n'/'“$location”'/{:a;/|}/{n;:b;p;n;bb;};n;ba;};'racktext.txt
#使用海绵覆盖管道中的文件
}
b| scribe racktext.txt
回音$
如果($matrix2==“是”);
然后
服务器读取
其他的
这已经完成了
fi
其他的
请重新运行此命令
出口
fi
}
服务器读取

以下
script.sh
适用于您提供的在stdin上传递的示例:

#!/bin/bash
while IFS= read -r l; do 
    if [[ "$l" =~ description ]]; then 
       msg="$l"$'\n'; 
    elif [[ "$l" =~ "}" ]]; then 
         { 
           echo -n "$msg" | grep -v '|-'; 
           echo '|16: servername;'; 
         } | sed 's/^|//' | sort -n | sed 's/^/|/' | while IFS= read -r l; do 
           echo "$l"; 
           echo '|-'; 
         done | head -n-1; 
         echo '|}'; 
     else 
         msg+="$l"$'\n'; 
     fi; 
done
对于以下输入:

|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername";
|-
|39: servername;
|-
|41: switch;
|}
它的输出如下:

|+  description = "5.1.1";
|-
|1: ~servername~ [4U];
|-
|5: servername [2U];
|-
|7: servername [2U];
|-
|9: servername [2U];
|-
|11: servername [2U];
|-
|15: servername [2U];
|-
|16: servername;
|-
|17: servername [2U];
|-
|19: servername [2U];
|-
|21: ~servername~ [2U];
|-
|23: servername [2U];
|-
|25: servername [2U];
|-
|29: servername [2U];
|-
|31: servername [2U];
|-
|33: servername [2U];
|-
|35: ~servername~ [2U];
|-
|37: ~servername";
|-
|39: servername;
|-
|41: switch;
|}
由于您没有提供此文件格式的任何说明或其他示例,我假设:

  • |-
    可以忽略和删除,并且永远不会更改(起初我以为这些是空的碎布,但后来它们介于15到16和17之间,所以不是)
  • 本节以描述开头,以
    |