バッシュ:文字列から改行文字を削除します (行を読み取ります)

StackOverflow https://stackoverflow.com/questions/1459250

  •  12-09-2019
  •  | 
  •  

質問

次の問題に遭遇しました。次のことを行う Linux bash スクリプトを作成しています。

  • ファイルから行を読み取る
  • 剥がす \n 読み取った行末の文字
  • そこにあるコマンドを実行します

例:コマンド.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

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

役に立ちましたか?

解決

いつも好きです 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

以下のコメントから、入力ファイルにキャリッジ リターン ( " " ) が含まれているのではないかと思われますが、これは改行とは異なります。入力ファイルはもともとDOS形式ですか?その場合、期待どおりの結果を得るには、2 バイトの DOS 行末「 」を 1 バイトの UNIX 行「 」に変換する必要があります。

これは、コメントアウトされた行の「 」を「 」に置き換えることで実行できるはずです。

他のヒント

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

本当にファイルの最初の行だけを実行したい場合は、次のようにします。 head -n 1 file |sh

キャリッジリターンに問題がある場合: tr -d '\r' <file |sh

これを試してみました:

read line
echo -n $line | od -x

入力「xxxx」の場合、次の結果が得られます。

0000000 7878 7878

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

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

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' 

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 ;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top