在多个shell中读取循环时保留反斜杠

时间:2015-07-26 06:51:22

标签: while-loop escaping sh portability backslash

我有以下代码:

#!/bin/sh
while read line; do
        printf "%s\n" $line
done < input.txt

Input.txt包含以下行:

one\two
eight\nine

输出如下

onetwo
eightnine

&#34;标准&#34;保留斜杠的解决方案是使用read -r。 但是,我有以下限制:

  • 必须在#!/bin/sh下运行,原因是可移植性/ posix合规性。
  • 并非所有系统 将支持-r开关在/ sh
  • 下阅读
  • 无法更改输入文件格式

因此,我正在寻找另一种方法来在读取行后保留反斜杠。我提出了一个有用的解决方案,即使用sed\替换为其他值(例如||)到一个临时文件中(从而绕过我上面的上一个要求)然后,在再次使用sed读取它们之后将其转换回来。像这样:

#!/bin/sh
sed -e 's/[\/&]/||/g' input.txt > tempfile.txt
while read line; do
        printf "%s\n" $line | sed -e 's/||/\\/g'
done < tempfile.txt

我认为必须有一个更优雅的&#34;这样做的方式。 一些想法: 1)使用命令替换将其存储到变量而不是文件中。问题 - 我不确定命令替换在这里是否可移植,我尝试使用变量而不是文件是不成功的。无论如何,基本解决方案的文件或变量实际上是相同的(两个替换)。

2)以某种方式使用IFS?我已经调查了一下,但不确定这可以帮助解决这个问题。

3)???

根据我的约束,有哪些更好的方法可以解决这个问题?

由于

2 个答案:

答案 0 :(得分:0)

你的约束似乎有点严格。这是我记下的一段代码(我不太确定你的while循环对于你想做的其他东西的价值有多大,所以我为了方便起见将其删除了。我不保证此代码具有健壮性。但无论如何,逻辑会给你提示你可能希望继续的方向。 (temp.dat是输入文件)

#!/bin/sh
var1="$(cut -d\\ -f1 temp.dat)"
var2="$(cut -d\\ -f2 temp.dat)"

iter=1

set -- $var2
for x in $var1;do
    if [ "$iter" -eq 1 ];then
        echo $x "\\"  $1
    else
        echo $x "\\" $2
    fi
    iter=$((iter+1))
done

答案 1 :(得分:0)

正如Larry Wall所说,编写便携式shell比编写便携式shell脚本更容易。

perl -lne 'print $_' input.txt

最简单的Perl脚本仍然比较简单,但我想你在打印之前想要用$_做一些事情。