Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File 当sed输出分配给文件中的变量时,echo是不同的_File_Bash_Shell_Sed_Echo - Fatal编程技术网

File 当sed输出分配给文件中的变量时,echo是不同的

File 当sed输出分配给文件中的变量时,echo是不同的,file,bash,shell,sed,echo,File,Bash,Shell,Sed,Echo,我正在编写一个shell脚本,它使用sed根据模式分割字符串行 #pattern 'string1','string2','string3' cat $FILENAME | while read LINE do firstPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\1/" ) secondPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)

我正在编写一个shell脚本,它使用sed根据模式分割字符串行

    #pattern 'string1','string2','string3'

    cat $FILENAME | while read LINE
    do

    firstPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\1/" )
    secondPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\2/" )
    thirdPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\3/" )

    done
我可以使用单独的回音打印它们,但如果我将它们放在一个回音中,如下图所示

    #if LINE from FILE is '123','abc','hello'

    echo "$firstPart $secondPart"
    #this prints " abc" instead of "123 abc"

    #try appending a string on echo
    echo "$firstPart -"
    #this prints " -3" instead of "123 -"
当我尝试在代码中的常量字符串中使用sed时,echo看起来不错

    #Correct Echo
    SOMESTRING='123','abc','hello'

    firstPart=$(echo "$SOMESTRING" | sed -r "s/'(.*)','(.*)','(.*)'/\1/" )
    secondPart=$(echo "$SOMESTRING" | sed -r "s/'(.*)','(.*)','(.*)'/\2/" )
    thirdPart=$(echo "$SOMESTRING" | sed -r "s/'(.*)','(.*)','(.*)'/\3/" )

    echo "$firstPart $secondPart"
    #this prints "123 abc"

当输入是文件中的一行时,这是sed的正确行为吗?如何使其表现为代码中包含并声明了该行(如我的第二个示例)。

当您对bash说
SOMESTRING='123'、'abc'、'hello'
时,它会去掉单引号:

$ echo "$SOMESTRING"
123,abc,hello
如果你想保留它们,你需要说
SOMESTRING=“'123','abc','hello'”

这意味着您的sed模式无法正常工作,例如,
firstPart
被设置为空字符串。如果您从sed模式中删除单引号,它就会工作

但是,我建议使用
IFS
拆分简单的分隔输入:

echo "'123','abc','hello'" | while IFS=, read a b c; do
  echo $a
  echo $b
  echo $c
done
或简述者:

while IFS=, read a b c; do echo -e "$a\n$b\n$c"; done <<< "'123','abc','hello'" 

我不是专家,但我可以告诉您,当您在管道中传输“while”脚本时,while中使用的变量在主脚本中不可用

while read LINE
do

firstPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\1/" )
secondPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\2/" )
thirdPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\3/" )
done < $FILENAME
例: 如果您在while循环中使用echo语句,它将显示SED的解析是正确的

您也可以使用以下语法在主脚本中公开这些变量

while read LINE
do

firstPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\1/" )
secondPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\2/" )
thirdPart=$(echo "$LINE" | sed -r "s/'(.*)','(.*)','(.*)'/\3/" )
done < $FILENAME
读取行时
做
第一部分=$(回显“$LINE”| sed-r“s/”(.*),(.*),(.*),(.*)/\1/”)
第二部分=$(回显“$LINE”| sed-r“s/”(.*),(.*),(.*),(.*)/\2/”)
第三部分=$(回显“$LINE”| sed-r“s/”(.*),(.*),(.*),(.*)/\3/”)
完成<$FILENAME

在我看来,字符串中嵌入了回车符(有时写为
\r
)。因此,当您执行
回显“$firstPart-”
,其中firstPart=“123\r”时,它会打印两行:

123
 -
…第二行打印在第一行之上(并覆盖第一行)。我的猜测是,您使用了一个使用DOS样式的行结尾的文本编辑器编辑了脚本(即,每行都以回车符结尾,后跟换行符),但是shell需要unix样式的行结尾(仅换行符),并将回车符视为命令的一部分(例如,
firstPart=$(echo“$SOMESTRING”| sed-r“s/”(.*),(.*),(.*),(.*),(.*))“/\1/”)\r
,其中将包括第一部分中的
\r


如果这是问题,运行脚本上的DOS2UNIX应该修复它(然后切换到一个不使用DOS风格的行结尾的编辑器)。< /P>如果回车返回在行的中间,DOS2UNIX将无济于事。请您需要<代码> TR -D′R′/代码>,请解释您的代码所做的以及为什么它解决了这个问题,谢谢!

SOMESTRING='123','abc','hello'

firstPart=$(echo "$SOMESTRING" | sed "s/\([^,]*\),\([^,]*\),\([^,]*\)/\1/" )
secondPart=$(echo "$SOMESTRING" | sed "s/\([^,]*\),\([^,]*\),\([^,]*\)/\2/" )
thirdPart=$(echo "$SOMESTRING" | sed "s/\([^,]*\),\([^,]*\),\([^,]*\)/\3/" )