Como passar linhas de um arquivo para um script bash, para que cada linha permaneça indivisa, mesmo que haja espaços?

2

Dado:

$ 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'

Como faço para alterar lines.txt ou 1.sh , para que 2.sh receba apenas dois argumentos:

  • a/b
  • c/d e/f

?

    
por mark 24.08.2011 / 18:39

3 respostas

1

Defina o IFS (separador de campo interno) como uma nova linha:

$ 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=
    
por 24.08.2011 / 19:39
0

Se você não está preso à idéia de usar o cat para enviar tantos argumentos quanto o arquivo é longo, você pode achar este método bastante flexível. Você pode canalizar o arquivo diretamente para 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 
    
por 24.08.2011 / 22:22
0

Se o seu arquivo de entrada contém a linha 'c/d e/f' e você deseja processar o item c/d e/f (sem as aspas), então você pode estar procurando xargs . Seu formato de entrada é uma lista de strings separadas por espaços, com os caracteres ' e " delimitando strings literais. Além disso, \ faz o próximo caractere ser interpretado literalmente, mas apenas fora de uma string. Por exemplo, aqui está um arquivo de entrada:

how\'dy 'hello world' aaa\
bbb

Os itens neste arquivo são how'dy , hello world e aaa␤bbb (onde é um caractere de nova linha).

    
por 24.08.2011 / 23:34