File 当sed输出分配给文件中的变量时,echo是不同的
我正在编写一个shell脚本,它使用sed根据模式分割字符串行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/'(.*)','(.*)','(.*)
#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/" )