为什么使用 awk 可以正常工作,但如果我将变量分配给所述 awk 命令,它会破坏其中包含 space 的任何内容?
Why does using using awk work fine, but if i assign a variable to said awk command it breaks anything that has a space in it?
我正在制作一个读取 CSV 的脚本,我在其中放置了我想放在停靠栏上的各种图标的位置。如果我运行
awk -F "," '{print } test.csv
我会得到:
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
但是如果我将相同的命令分配给变量 this 和 运行
for i in $this; do
echo $i;
最后三行打印如下:
/Applications/Microsoft\
Word
/Applications/Microsoft\
Excel
/Applications/Microsoft\
Powerpoint
我知道它在 space 处明显坏了,需要修复它,但我不明白为什么它在一个中有效,但在另一个中无效。 强文本
默认情况下,Bash for 循环在所有空格处拆分,您可以通过在循环
之前设置 IFS=$'\n'
来覆盖它
测试结果:
akshay@db-3325:/tmp$ cat testfile
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
假设您使用 awk 存储结果,如下所示
akshay@db-3325:/tmp$ testvar=$(awk '1' testfile)
默认行为
akshay@db-3325:/tmp$ for i in $testvar; do echo "$i"; done
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\
Word
/Applications/Microsoft\
Excel
/Applications/Microsoft\
Powerpoint
这是 IFS
akshay@db-3325:/tmp$ IFS=$'\n';for i in $testvar; do echo "$i"; done;
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
在您的代码中:
for i in $this; do
echo $i;
$this
被扩展,然后被 Internal Field Separator ($IFS
) 变量中的任何字符拆分,默认情况下是制表符、换行符和 space。为了获得您想要的行为,我们只希望字符串在换行符上拆分,因此我们使用以下方法将 IFS 设置为换行符:
IFS=$'\n'
应谨慎使用 IFS,建议将原始 IFS 值保存在另一个变量中,并在使用修改后的 IFS 后恢复它们。
或恢复原状:
IFS=$' \t\n'
总之:
IFS=$'\n'
for i in $this; do
echo $i;
IFS=$' \t\n'
应该输出你想要的。
回答为什么会这样。 awk
输出不受 globbing 或拆分的影响,变量的扩展内容是。
要么
awk -F "," '{print } test.csv | while IFS= read -r line; do
do_stuff_with "$line"
done
或者完全跳过 awk
while IFS=, read -r first restOfList; do
do_stuff_with "$first"
done < test.csv
资源:
我正在制作一个读取 CSV 的脚本,我在其中放置了我想放在停靠栏上的各种图标的位置。如果我运行
awk -F "," '{print } test.csv
我会得到:
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
但是如果我将相同的命令分配给变量 this 和 运行
for i in $this; do
echo $i;
最后三行打印如下:
/Applications/Microsoft\
Word
/Applications/Microsoft\
Excel
/Applications/Microsoft\
Powerpoint
我知道它在 space 处明显坏了,需要修复它,但我不明白为什么它在一个中有效,但在另一个中无效。 强文本
默认情况下,Bash for 循环在所有空格处拆分,您可以通过在循环
之前设置IFS=$'\n'
来覆盖它
测试结果:
akshay@db-3325:/tmp$ cat testfile
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
假设您使用 awk 存储结果,如下所示
akshay@db-3325:/tmp$ testvar=$(awk '1' testfile)
默认行为
akshay@db-3325:/tmp$ for i in $testvar; do echo "$i"; done
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\
Word
/Applications/Microsoft\
Excel
/Applications/Microsoft\
Powerpoint
这是 IFS
akshay@db-3325:/tmp$ IFS=$'\n';for i in $testvar; do echo "$i"; done;
/Applications/Launchpad
/Applications/Safari
/Applications/Pages
/Applications/Numbers
/Applications/Keynote
/Applications/Photos
/Applications/iMovie
/Applications/GarageBand
/Applications/Microsoft\ Word
/Applications/Microsoft\ Excel
/Applications/Microsoft\ Powerpoint
在您的代码中:
for i in $this; do
echo $i;
$this
被扩展,然后被 Internal Field Separator ($IFS
) 变量中的任何字符拆分,默认情况下是制表符、换行符和 space。为了获得您想要的行为,我们只希望字符串在换行符上拆分,因此我们使用以下方法将 IFS 设置为换行符:
IFS=$'\n'
应谨慎使用 IFS,建议将原始 IFS 值保存在另一个变量中,并在使用修改后的 IFS 后恢复它们。
或恢复原状:
IFS=$' \t\n'
总之:
IFS=$'\n'
for i in $this; do
echo $i;
IFS=$' \t\n'
应该输出你想要的。
回答为什么会这样。 awk
输出不受 globbing 或拆分的影响,变量的扩展内容是。
要么
awk -F "," '{print } test.csv | while IFS= read -r line; do
do_stuff_with "$line"
done
或者完全跳过 awk
while IFS=, read -r first restOfList; do
do_stuff_with "$first"
done < test.csv
资源: