12

私は次の問題にぶつかりました:私は次のことを行うLinuxbashスクリプトを書いています:

  • ファイルから行を読み取る
  • \n読んだばかりの行の終わりから文字を削除します
  • そこにあるコマンドを実行します

例:commands.txt

ls
ls -l
ls -ltra
ps as

bashファイルを実行すると、最初の行を取得して実行する必要がありますが、\n現在のところ、シェルは「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

SOに尋ねる前に私が試したことがあるとコメントしました。解決策はありますか?私はこれでここ数時間頭を壊している...

4

7 に答える 7

18

perl -ne 'chomp and print'改行をトリミングするために、私はいつも好きです。覚えやすくていい。

例えばls -l | perl -ne 'chomp and print'

でも

しかし、それはあなたの問題ではないと思います。ファイル内のコマンドをシェルスクリプトの「読み取り」に渡す方法を理解しているかどうかはわかりませんが。

このような私自身のテストスクリプト(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 ラインを 1 バイトの UNIX ラインである "\n" に変換する必要があります。

コメントアウトされた行のいずれかで「\ n」を「\ r」に交換することで、これを行うことができるはずです。

于 2009-09-22T10:30:43.713 に答える
14

誰かがすでにシェルコマンドを実行するプログラムを書いています: sh ファイル

本当にファイルの最初の行だけを実行したい場合:head -n 1 file |sh

問題が改行である場合:tr -d '\r' <file |sh

于 2009-09-22T12:15:54.077 に答える
2

私はこれを試しました:

read line
echo -n $line | od -x

入力「xxxx」については、次のようになります。

0000000 7878 7878

ご覧のとおり\n、変数の内容の最後には no がありません。-xオプション( )を指定してスクリプトを実行することをお勧めしますbash -x script。これにより、実行されるすべてのコマンドが出力されます。

[編集] 問題は、Windows で commands.txt を編集したことです。現在、ファイルには、混乱を招く行区切り文字として CRLF (0d0a) が含まれています (read既知ls\rのコマンドではありません)。dos2unixまたは同様のものを使用して、Unix ファイルに変換します。

于 2009-09-22T10:28:50.373 に答える
2

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' 
于 2009-09-22T15:45:53.053 に答える
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
于 2009-09-22T10:58:14.993 に答える
0

次のスクリプトは機能します(少なくとも私にとっては):

#!/bin/bash

while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
于 2009-09-22T11:05:35.760 に答える
0

では機能しませんが、のオプションlsを確認することをお勧めしますfind-print0

于 2009-09-22T10:26:47.367 に答える