BASH:从string中去掉换行符(读取行)

我碰到以下问题:我正在写一个Linux bash脚本,它执行以下操作:

  • 从文件读取行
  • 从刚刚阅读的行尾删除\n字符
  • 执行那里的命令

例如:commands.txt

 ls ls -l ls -ltra ps as 

bash文件的执行应该得到第一行,并执行它,但是\n目前,shell只输出“command not found:ls”脚本的这部分看起来像这样

  read line if [ -n "$line" ]; then #if not empty line #myline=`echo -n $line | tr -d '\n'` #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'` myline=`echo -n $line | tr -d "\n"` $myline #execute it cat $fname | tail -n+2 > $fname.txt mv $fname.txt $fname fi 

评论你有我之前试过的东西。 任何解决scheme 过去的几个小时,我砸了我的脑袋。

Solutions Collecting From Web of "BASH:从string中去掉换行符(读取行)"

我总是喜欢perl -ne 'chomp and print' ,来修剪换行符。 很好,很容易记住。

例如ls -l | perl -ne 'chomp and print' ls -l | perl -ne 'chomp and print'

然而

我不认为这是你的问题。 虽然我不确定我是否理解如何将文件中的命令传递给shell脚本中的“read”。

用我自己的测试脚本(test.sh)

 read line if [ -n "$line" ]; then $line fi 

和一个像这样的样本输入文件(test.cmds)

 ls ls -l ls -ltra 

如果我像这样运行./test.sh < test.cmds ,我会看到预期的结果,即在当前工作目录上运行第一个命令“ls”。

也许你的输入文件中有其他不可打印的字符?

我看起来像这样

 od -c test.cmds 0000000 ls \nls - l \nls - lt 0000020 ra \n 0000023 

从下面的注释中,我怀疑你的输入文件中可能有回车符(“\ r”),这与换行符不一样。 原来是DOS格式的输入文件? 如果是这样的话,则需要将2字节的DOS行结尾“\ r \ n”转换为单个字节UNIX“\ n”来实现预期的结果。

你应该可以通过在你的任何注释掉的行中交换“\ r”的“\ n”来做到这一点。

有人已经写了一个执行shell命令的程序:sh文件

如果你真的只想执行一个文件的第一行: head -n 1 file |sh

如果你的问题是回车: tr -d '\r' <file |sh

我试过这个:

 read line echo -n $line | od -x 

对于输入'xxxx',我得到:

 0000000 7878 7878 

正如你所看到的,变量内容的末尾没有\n 。 我建议使用选项-xbash -x script )运行bash -x script 。 这将在执行时打印所有命令。

[编辑]你的问题是,你在Windows上编辑commands.txt。 现在,该文件包含CRLF(0d0a)作为行分隔符混淆read (和ls\r不是已知的命令)。 使用dos2unix或类似的把它变成一个Unix文件。

你也可以试着用换行符替换回车符,只用Bash builtins:

 line=$'a line\r' line="${line//$'\r'/$'\n'}" #line="${line/%$'\r'/$'\n'}" # replace only at line end printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 

你需要eval命令

 #!/bin/bash -x while read cmd do if [ "$cmd" ] then eval "$cmd" fi done 

我跑了
./script.sh <file.txt

而file.txt是:

 LS
 ls -l
 ls -ltra
 ps as

虽然不适用于ls ,但我建议查看find-print0选项

以下脚本(至少对我来说)起作用:

 #!/bin/bash while read I ; do if [ "$I" ] ; then $I ; fi ; done ;