我正在尝试从管道分隔文件中提取字段,并将它们作为参数提供给循环中的外部程序。该文件包含以下行:
value1|value2
value3|value4
所以我想出了:
while read line;
do echo -n "${line}" | awk -F '|' '{print $1}';
echo -n " something ";
echo -n "${line}" | awk -F '|' '{print $2}';
echo " somethingelse";
done < <(cat $FILE)
我想看到以下输出:
value1 something value2 somethingelse
value3 something value4 somethingelse
但相反,我得到了:
value1
something value2
somethingelse
value3
something value4
somethingelse
也许我不应该使用echo?
答案 0 :(得分:2)
如果您awk
支持printf
,我会改用它。即使echo -n
未添加换行符,awk {print}
也会如此。 printf
变体不会像print
那样将换行符放在最后:
echo -n "${line}" | awk -F '|' '{printf "%s", $1}'
这是您的十六进制转储版本,当您通过\n
时,请注意最后的awk
:
pax> echo -n "hello|goodbye" | od -xcb
0000000 6568 6c6c 7c6f 6f67 646f 7962 0065
h e l l o | g o o d b y e
150 145 154 154 157 174 147 157 157 144 142 171 145
0000015
pax> echo -n "hello|goodbye" | awk -F '|' '{print $1}' | od -xcb
0000000 6568 6c6c 0a6f
h e l l o \n
150 145 154 154 157 012
这是printf
版本:
pax> echo -n "hello|goodbye" | awk -F '|' '{printf "%s", $1}' | od -xcb
0000000 6568 6c6c 006f
h e l l o
150 145 154 154 157
就是这样,在您的真实文件上运行(在此示例中名为FILE以简化我的测试):
pax> while read line;
do
echo -n "${line}" | awk -F '|' '{printf "%s", $1}';
echo -n " something ";
echo -n "${line}" | awk -F '|' '{printf "%s", $2}';
echo " somethingelse";
done < <(cat FILE)
value1 something value2 somethingelse
value3 something value4 somethingelse
答案 1 :(得分:1)
@OP,无需使用cat
。同样在while循环中,您可以将IFS(输入字段分隔符)设置为管道|
,并且不需要为解析的每一行使用外部命令。效率低下。以下是仅使用shell
while IFS="|" read -r a b
do
echo "$a something $b somethingelse" # use echo without -n
done <"file"
您还可以使用比printf
更便携的echo
。
输出
$ ./shell.sh
value1 something value2 somethingelse
value3 something value4 somethingelse
答案 2 :(得分:0)
您可以使用sed
:
$ cat test
value1|value2
value3|value4
$ sed 's/|/ something /; s/$/ somethingelse/' test
value1 something value2 somethingelse
value3 something value4 somethingelse
$
更新:
对于原始问题,您可以删除tr -d '\012'
的换行符,例如
cat ${FILE} | while read line
do
echo "${line}" | awk -F '|' '{print $1}' | tr -d '\012'
echo -n " something "
echo "${line}" | awk -F '|' '{print $2}' | tr -d '\012'
echo " somethingelse"
done
答案 3 :(得分:0)
while read line;
do
echo "${line}" | sed s/'|'/' something '/| sed s/$/' somethingelse'/;
done < file1