Linux BASH:从字符串中去除换行符(读取行)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1459250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BASH: Strip new-line character from string (read line)
提问by Bogdan Constantinescu
I bumped into the following problem: I'm writing a Linux bash script which does the following:
我遇到了以下问题:我正在编写一个 Linux bash 脚本,它执行以下操作:
- Read line from file
- Strip the
\n
character from the end of the line just read - Execute the command that's in there
- 从文件中读取行
\n
从刚读过的行尾去掉字符- 执行里面的命令
Example: commands.txt
示例:commands.txt
ls
ls -l
ls -ltra
ps as
The execution of the bash file should get the first line, and execute it, but while the \n
present, the shell just outputs "command not found: ls"
That part of the script looks like this
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
Commented you have the things I tried before asking SO. Any solutions? I'm smashing my brains for the last couple of hours over this...
评论说你有我在问 SO 之前尝试过的东西。任何解决方案?在过去的几个小时里,我正在为此绞尽脑汁......
采纳答案by cms
I always like perl -ne 'chomp and print'
, for trimming newlines. Nice and easy to remember.
我总是喜欢perl -ne 'chomp and print'
, 用于修剪换行符。好记又好记。
e.g. ls -l | perl -ne 'chomp and print'
例如 ls -l | perl -ne 'chomp and print'
However
然而
I don't think that is your problem here though. Although I'm not sure I understand how you're passing the commands in the file through to the 'read' in your shell script.
我不认为这是你的问题。虽然我不确定我是否理解您如何将文件中的命令传递到 shell 脚本中的“读取”。
With a test script of my own like this (test.sh)
使用我自己的测试脚本(test.sh)
read line
if [ -n "$line" ]; then
$line
fi
and a sample input file like this (test.cmds)
和这样的示例输入文件(test.cmds)
ls
ls -l
ls -ltra
If I run it like this ./test.sh < test.cmds
, I see the expected result, which is to run the first command 'ls' on the current working directory.
如果我像这样运行它./test.sh < test.cmds
,我会看到预期的结果,即在当前工作目录上运行第一个命令 'ls'。
Perhaps your input file has additional non-printable characters in it ?
也许您的输入文件中有额外的不可打印字符?
mine looks like this
我的看起来像这样
od -c test.cmds
0000000 l s \n l s - l \n l s - l t
0000020 r a \n
0000023
From your comments below, I suspect you may have carriage returns ( "\r" ) in your input file, which is not the same thing as a newline. Is the input file originally in DOS format ? If so, then you need to convert the 2 byte DOS line ending "\r\n" to the single byte UNIX one, "\n" to achieve the expected results.
根据您下面的评论,我怀疑您的输入文件中可能有回车符 ( "\r" ),这与换行符不同。输入文件最初是 DOS 格式吗?如果是这样,那么您需要将以“\r\n”结尾的 2 字节 DOS 行转换为单字节 UNIX 行“\n”以达到预期的结果。
You should be able to do this by swapping the "\n" for "\r" in any of your commented out lines.
您应该能够通过在任何注释掉的行中将 "\n" 交换为 "\r" 来做到这一点。
回答by knittl
回答by Aaron Digulla
I tried this:
我试过这个:
read line
echo -n $line | od -x
For the input 'xxxx', I get:
对于输入'xxxx',我得到:
0000000 7878 7878
As you can see, there is no \n
at the end of the contents of the variable. I suggest to run the script with the option -x
(bash -x script
). This will print all commands as they are executed.
如您所见,\n
变量内容的末尾没有。我建议使用选项-x
( bash -x script
)运行脚本。这将在执行时打印所有命令。
[EDIT] Your problem is that you edited commands.txt on Windows. Now, the file contains CRLF (0d0a) as line delimiters which confuses read
(and ls\r
is not a known command). Use dos2unix
or similar to turn it into a Unix file.
[编辑] 你的问题是你在 Windows 上编辑了 commands.txt。现在,该文件包含 CRLF (0d0a) 作为令人困惑的行分隔符read
(并且ls\r
不是已知命令)。使用dos2unix
或 类似方法将其转换为 Unix 文件。
回答by sud03r
you need eval command
你需要 eval 命令
#!/bin/bash -x
while read cmd
do
if [ "$cmd" ]
then
eval "$cmd"
fi
done
I ran it as
./script.sh < file.txt
我将它作为
./script.sh < file.txt 运行
And file.txt was:
而 file.txt 是:
ls ls -l ls -ltra ps as
回答by dsm
The following script works (at least for me):
以下脚本有效(至少对我而言):
#!/bin/bash
while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
回答by Mark Edgar
Someone already wrote a program which executes shell commands: sh file
有人已经写了一个执行shell命令的程序:sh file
If you really only want to execute the first line of a file: head -n 1 file |sh
如果您真的只想执行文件的第一行: head -n 1 file |sh
If your problem is carriage-returns: tr -d '\r' <file |sh
如果您的问题是回车: tr -d '\r' <file |sh
回答by Mark Edgar
You may also try to replace carriage returns with newlines only using Bash builtins:
您也可以尝试仅使用 Bash 内置函数用换行符替换回车符:
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'