Bash: 在 for 循环中 echo $variable 后追加字符
Bash: Append character(s) after echo $variable in a for loop
我正在尝试解析一个 csv 文件并从字段中获取某些值,这有效:
$ for line in $(cat test.csv); do regiovalue="$(echo $line | awk -F';' '{print }')"; echo "regio: ${regiovalue}"; done
regio: TOG
regio: APP
regio: APP
regio: APP
但我需要在回显输出的末尾附加另一个字符:
$ for line in $(cat test.csv); do regiovalue="$(echo $line | awk -F';' '{print }')"; echo "regio: ${regiovalue};"; done
;egio: TOG
;egio: APP
;egio: APP
;egio: APP
如您所见,添加的分号字符已添加到该行的开头并替换了该行的第一个字符 (r)。顺便说一句,它是分号还是任何其他字符都没有关系。
这只发生在一个循环中(包括 for 和 while read 测试),一个简单的 echo 没有问题:
$ regiovalue=TOG; echo "regio: ${regiovalue};"
regio: TOG;
Bash版本:
$ bash --version | grep bash
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
- 为什么会这样?我检查了文档,但没有找到任何关于循环中字符替换的特殊信息。
- 如何在单个回显中获得输出(变量值和附加字符)?
这里的问题是您的行可能以 \r
结尾...这会导致光标 return 到行的开头(carriage return).
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0d 0a 68 6f 77 0d 0a 61 72 65 0d |hello..how..are.|
00000010 0a 79 6f 75 0d 0a |.you..|
00000016
你应该过滤掉它,可能使用 tr
:
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | tr -d $'\r' \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0a 68 6f 77 0a 61 72 65 0a 79 6f |hello.how.are.yo|
00000010 75 0a |u.|
00000012
或设置awk
的记录分隔符:
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | awk -vRS='\r\n' '{print [=12=]}' \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0a 68 6f 77 0a 61 72 65 0a 79 6f |hello.how.are.yo|
00000010 75 0a |u.|
00000012
正如 dawg 所指出的,您可以只使用 awk
来完成所有事情:
awk -vRS='\r\n' -F';' '{print "regio: " }' < test.csv
我正在尝试解析一个 csv 文件并从字段中获取某些值,这有效:
$ for line in $(cat test.csv); do regiovalue="$(echo $line | awk -F';' '{print }')"; echo "regio: ${regiovalue}"; done
regio: TOG
regio: APP
regio: APP
regio: APP
但我需要在回显输出的末尾附加另一个字符:
$ for line in $(cat test.csv); do regiovalue="$(echo $line | awk -F';' '{print }')"; echo "regio: ${regiovalue};"; done
;egio: TOG
;egio: APP
;egio: APP
;egio: APP
如您所见,添加的分号字符已添加到该行的开头并替换了该行的第一个字符 (r)。顺便说一句,它是分号还是任何其他字符都没有关系。
这只发生在一个循环中(包括 for 和 while read 测试),一个简单的 echo 没有问题:
$ regiovalue=TOG; echo "regio: ${regiovalue};"
regio: TOG;
Bash版本:
$ bash --version | grep bash
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
- 为什么会这样?我检查了文档,但没有找到任何关于循环中字符替换的特殊信息。
- 如何在单个回显中获得输出(变量值和附加字符)?
这里的问题是您的行可能以 \r
结尾...这会导致光标 return 到行的开头(carriage return).
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0d 0a 68 6f 77 0d 0a 61 72 65 0d |hello..how..are.|
00000010 0a 79 6f 75 0d 0a |.you..|
00000016
你应该过滤掉它,可能使用 tr
:
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | tr -d $'\r' \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0a 68 6f 77 0a 61 72 65 0a 79 6f |hello.how.are.yo|
00000010 75 0a |u.|
00000012
或设置awk
的记录分隔符:
$ printf "hello\r\nhow\r\nare\r\nyou\r\n" \
> | awk -vRS='\r\n' '{print [=12=]}' \
> | hexdump -Cv
00000000 68 65 6c 6c 6f 0a 68 6f 77 0a 61 72 65 0a 79 6f |hello.how.are.yo|
00000010 75 0a |u.|
00000012
正如 dawg 所指出的,您可以只使用 awk
来完成所有事情:
awk -vRS='\r\n' -F';' '{print "regio: " }' < test.csv