空白があっても各行が無制限に保たれるようにファイルから bash スクリプトに行を渡すにはどうすればよいですか?

空白があっても各行が無制限に保たれるようにファイルから bash スクリプトに行を渡すにはどうすればよいですか?

一方:

$ cat lines.txt
a/b
'c/d e/f'

$ cat 1.sh
#!/bin/sh
./2.sh `cat lines.txt`

$ cat 2.sh
#!/bin/sh
echo p1=$1
echo p2=$2
echo p3=$3

$ ./1.sh
p1=a/b
p2='c/d
p3=e/f'

2つの引数だけを受け取るようlines.txtに変更1.shするにはどうすればよいですか?2.sh

  • a/b
  • c/d e/f

答え1

IFS(内部フィールド区切り文字)を改行に設定します。

$ cat 1.sh 
#!/bin/sh
OLD_IFS=$IFS
IFS="
"
./2.sh `cat lines.txt`
IFS=$OLD_IFS

$ ./1.sh
p1=a/b
p2='c/d e/f'
p3=

答え2

catを使用してファイルの長さと同じ数の引数を送信するというアイデアにとらわれない場合は、この方法が非常に柔軟であることがわかります。ファイルを2.shに直接パイプできます。

# echo -e "a/b\n'c/d e/f'" >lines.txt

fn2.sh() { set -f              # disable pathname expansion 
   while IFS= read -r line; do # -r prevents expansion of such things as \n
       printf "%s\n" "$line"   # printf is more robust than echo (when dealing with unknown data)
   done 
}
< lines.txt fn2.sh             # using redirection 

答え3

入力ファイルにその行が含まれていて、'c/d e/f'アイテムを処理したい場合c/d e/f(引用符なし)、おそらく次のものを探しています。xargs。入力形式は、文字'"区切られたリテラル文字列を含むスペースで区切られた文字列のリストです。また、\次の文字は文字通り解釈されますが、文字列の外側でのみ解釈されます。たとえば、次は入力ファイルです。

how\'dy 'hello world' aaa\
bbb

このファイルの項目はhow'dyhello worldaaa␤bbb(改行文字はどこにありますか?) です。

関連情報