2009-09-22 68 views
11

我碰到了下面的問題:我在寫一個Linux的bash腳本,執行以下操作:BASH:從字符串地帶換行符(讀取線)

  • 讀線從文件
  • 地帶從行的端部的\n字符剛讀
  • 執行這就是在那裏

實施例的命令: commands.txt中

ls 
ls -l 
ls -ltra 
ps as 

bash的文件的執行應該得到的第一行,並執行它,但同時\n目前,外殼只是輸出「找不到命令: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 

評論你有我嘗試之前嘗試過的東西。任何解決方案我砸我的大腦在過去的幾個在這個時間......

+0

你是否簡單地試過'$ line'? – knittl 2009-09-22 10:31:55

+0

當然,我做到了。但它說:「命令沒有找到:ls 」 – 2009-09-22 10:36:44

+0

所需要的只是:'myline =「$(echo -n」$ line「)」'(如果需要,使用反引號代替'$()') – jnylen 2009-09-22 12:38:07

回答

17

我總是喜歡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 l s  \n l s  - l \n l s  - l t 
0000020 r a \n              
0000023 

從下面您的意見,我懷疑你可能在你的輸入文件,這是不一樣的東西作爲一個換行符回車(「\ r」)。輸入文件最初是否是DOS格式?如果是這樣,那麼您需要將結尾爲「\ r \ n」的2字節DOS行轉換爲單字節UNIX「\ n」以實現預期結果。

您應該可以通過在任何註釋掉的行中交換「\ r」中的「\ n」來完成此操作。

+1

我忘了提及這個文件是從samba共享的Windows中寫入的,我完全忘了我應該尋找'\ r'而不是'\ n'。我投了一票,非常感謝! – 2009-09-22 11:20:55

0

雖然不是ls工作,我建議你在看看find-print0選項

2

我嘗試這樣做:

read line 
echo -n $line | od -x 

對於輸入 'XXXX',我得到:

0000000 7878 7878 

正如你所看到的,有沒有\n在變量內容的結尾。我建議使用選項-xbash -x script)運行腳本。這將在執行時打印所有命令。

[編輯]你的問題是你在Windows上編輯了commands.txt。現在,該文件包含CRLF(0d0a)作爲行分隔符,它會混淆read(而ls\r不是已知命令)。使用dos2unix或類似的把它變成一個Unix文件。

+0

事情是我不從鍵盤讀取。我將STDIN更改爲一個文件(上面的command.txt),如果我在$'之間回顯$行,就會得到輸出'ls ' – 2009-09-22 10:31:34

+0

我得到的輸出是'echo -n $ line | od -x'是「0000000 736c 000d 0000003」 – 2009-09-22 10:35:55

+1

0d是回車符。與換行 – cms 2009-09-22 10:52:29

1

你需要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 
+0

'eval'也不起作用 – 2009-09-22 11:19:03

0

下面的腳本作品(至少對我而言):

#!/bin/bash 

while read I ; do if [ "$I" ] ; then $I ; fi ; done ; 
12

有人已經寫了一個程序,它執行shell命令:sh的文件

如果你真的只需要執行一個文件的第一行:head -n 1 file |sh

如果你的問題是回車符號:tr -d '\r' <file |sh

+0

當然是的,但是我的批處理文件的一部分。它不僅僅是一個簡單的執行命令,如果僅僅是這個,我肯定只使用'sh' – 2009-09-23 06:34:21

2

你也可以嘗試用換行符替換回車,只用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'